From e304d670353a8a4585eba6df26434bb66dc4855f Mon Sep 17 00:00:00 2001 From: RobertBeekman Date: Sun, 10 Dec 2023 22:44:03 +0100 Subject: [PATCH] Workshop - Simplify upload to a busy indicator, show images in profiles --- src/Artemis.Core/Constants.cs | 7 +- .../Artemis.UI.Shared.csproj | 3 + src/Artemis.UI.Shared/Styles/Border.axaml | 2 +- .../Utilities/ProgressableStreamContent.cs | 119 ------------------ src/Artemis.UI/Assets/Animations/busy.json | 1 + .../Entries/Details/EntryImageView.axaml | 29 +++-- .../Entries/Details/EntryImageViewModel.cs | 5 +- .../Entries/Details/EntryImagesView.axaml | 36 +++--- .../Workshop/Entries/EntriesView.axaml | 2 +- .../Image/ImagePropertiesDialogView.axaml.cs | 3 +- .../Workshop/Image/ImageSubmissionView.axaml | 2 +- .../Image/ImageSubmissionViewModel.cs | 20 +-- .../Library/SubmissionDetailViewModel.cs | 2 +- .../Workshop/Profile/ProfileDetailsView.axaml | 8 +- .../Steps/ImagesStepViewModel.cs | 22 +++- .../Steps/UploadStepView.axaml | 16 +-- .../Steps/UploadStepViewModel.cs | 68 +++------- .../UploadHandlers/IEntryUploadHandler.cs | 2 +- .../LayoutEntryUploadHandler.cs | 4 +- .../ProfileEntryUploadHandler.cs | 4 +- .../Services/Interfaces/IWorkshopService.cs | 4 +- .../Services/WorkshopService.cs | 8 +- 22 files changed, 125 insertions(+), 242 deletions(-) delete mode 100644 src/Artemis.UI.Shared/Utilities/ProgressableStreamContent.cs create mode 100644 src/Artemis.UI/Assets/Animations/busy.json diff --git a/src/Artemis.Core/Constants.cs b/src/Artemis.Core/Constants.cs index ba47fd52c..61381faf4 100644 --- a/src/Artemis.Core/Constants.cs +++ b/src/Artemis.Core/Constants.cs @@ -47,6 +47,7 @@ public static class Constants /// The full path to the Artemis logs folder /// public static readonly string LogsFolder = Path.Combine(DataFolder, "Logs"); + /// /// The full path to the Artemis logs folder /// @@ -71,9 +72,9 @@ public static class Constants /// /// The current version of the application /// - public static readonly string CurrentVersion = CoreAssembly.GetCustomAttribute()!.InformationalVersion != "1.0.0" - ? CoreAssembly.GetCustomAttribute()!.InformationalVersion - : "local"; + public static readonly string CurrentVersion = CoreAssembly.GetCustomAttribute()!.InformationalVersion.StartsWith("1.0.0") + ? "local" + : CoreAssembly.GetCustomAttribute()!.InformationalVersion; /// /// The plugin info used by core components of Artemis diff --git a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj index e37523b1d..10c5f8842 100644 --- a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj +++ b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj @@ -30,6 +30,9 @@ + + ..\..\..\..\Users\Robert\.nuget\packages\asyncimageloader.avalonia\3.2.1\lib\netstandard2.1\AsyncImageLoader.Avalonia.dll + ..\..\..\RGB.NET\bin\net7.0\RGB.NET.Layout.dll diff --git a/src/Artemis.UI.Shared/Styles/Border.axaml b/src/Artemis.UI.Shared/Styles/Border.axaml index e3997e5ec..f5b71d793 100644 --- a/src/Artemis.UI.Shared/Styles/Border.axaml +++ b/src/Artemis.UI.Shared/Styles/Border.axaml @@ -4,7 +4,7 @@ I'm in a panel yo! - + I'm in a panel yo! diff --git a/src/Artemis.UI.Shared/Utilities/ProgressableStreamContent.cs b/src/Artemis.UI.Shared/Utilities/ProgressableStreamContent.cs deleted file mode 100644 index bac5bb9d1..000000000 --- a/src/Artemis.UI.Shared/Utilities/ProgressableStreamContent.cs +++ /dev/null @@ -1,119 +0,0 @@ -// Heavily based on: -// SkyClip -// - ProgressableStreamContent.cs -// -------------------------------------------------------------------- -// Author: Jeff Hansen -// Copyright (C) Jeff Hansen 2015. All rights reserved. - -using System; -using System.IO; -using System.Net; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - -namespace Artemis.UI.Shared.Utilities; - -/// -/// Provides HTTP content based on a stream with support for IProgress. -/// -public class ProgressableStreamContent : StreamContent -{ - private const int DEFAULT_BUFFER_SIZE = 4096; - - private readonly int _bufferSize; - private readonly IProgress _progress; - private readonly Stream _streamToWrite; - private bool _contentConsumed; - - /// - /// Initializes a new instance of the class. - /// - /// The stream to write. - /// The downloader. - public ProgressableStreamContent(Stream streamToWrite, IProgress progress) : this(streamToWrite, DEFAULT_BUFFER_SIZE, progress) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The stream to write. - /// The buffer size. - /// The downloader. - public ProgressableStreamContent(Stream streamToWrite, int bufferSize, IProgress progress) : base(streamToWrite, bufferSize) - { - if (bufferSize <= 0) - throw new ArgumentOutOfRangeException(nameof(bufferSize)); - - _streamToWrite = streamToWrite; - _bufferSize = bufferSize; - _progress = progress; - } - - /// - protected override void Dispose(bool disposing) - { - if (disposing) - _streamToWrite.Dispose(); - - base.Dispose(disposing); - } - - /// - protected override async Task SerializeToStreamAsync(Stream stream, TransportContext? context) - { - await SerializeToStreamAsync(stream, context, CancellationToken.None); - } - - /// - protected override async Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cancellationToken) - { - PrepareContent(); - - byte[] buffer = new byte[_bufferSize]; - long size = _streamToWrite.Length; - int uploaded = 0; - - await using (_streamToWrite) - { - while (!cancellationToken.IsCancellationRequested) - { - int length = await _streamToWrite.ReadAsync(buffer, cancellationToken); - if (length <= 0) - break; - - uploaded += length; - _progress.Report(new StreamProgress(uploaded, size)); - await stream.WriteAsync(buffer, 0, length, cancellationToken); - } - } - } - - /// - protected override bool TryComputeLength(out long length) - { - length = _streamToWrite.Length; - return true; - } - - /// - /// Prepares the content. - /// - /// The stream has already been read. - private void PrepareContent() - { - if (_contentConsumed) - { - // If the content needs to be written to a target stream a 2nd time, then the stream must support - // seeking (e.g. a FileStream), otherwise the stream can't be copied a second time to a target - // stream (e.g. a NetworkStream). - if (_streamToWrite.CanSeek) - _streamToWrite.Position = 0; - else - throw new InvalidOperationException("The stream has already been read."); - } - - _contentConsumed = true; - } -} \ No newline at end of file diff --git a/src/Artemis.UI/Assets/Animations/busy.json b/src/Artemis.UI/Assets/Animations/busy.json new file mode 100644 index 000000000..6c8fdd1d5 --- /dev/null +++ b/src/Artemis.UI/Assets/Animations/busy.json @@ -0,0 +1 @@ +{"v":"5.9.6","fr":29.9700012207031,"ip":0,"op":17.0000006924242,"w":1080,"h":1080,"nm":"dog","ddd":0,"assets":[{"id":"comp_0","nm":"1","fr":29.9700012207031,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[571.5,705,0],"ix":2,"l":2},"a":{"a":0,"k":[31.5,132,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[103,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":4,"s":[78,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":9,"s":[103,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":12,"s":[78,100,100]},{"t":17.0000006924242,"s":[103,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-206,132],[269,132]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":22,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.000024438501,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"ball Outlines","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[26.5,35.867,0],"ix":2,"l":2},"a":{"a":0,"k":[13.842,13.842,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-7.507],[7.507,0],[0,7.507],[-7.506,0]],"o":[[0,7.507],[-7.506,0],[0,-7.507],[7.507,0]],"v":[[13.592,0],[0,13.592],[-13.592,0],[0,-13.592]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203373763141,0.203600565592,0.203484329523,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[13.842,13.842],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.000024438501,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"wire Outlines","parent":4,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":3,"s":[-28]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":6,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":10,"s":[-34]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":13,"s":[5]},{"t":17.0000006924242,"s":[0]}],"ix":10},"p":{"a":0,"k":[85.395,20.574,0],"ix":2,"l":2},"a":{"a":0,"k":[17.5,17.5,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-1.103,-3.49]],"o":[[0,0],[0,0]],"v":[[-2.663,-4.868],[2.663,4.868]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.999998743394,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[20.163,22.368],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.000024438501,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"band Outlines","parent":12,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":3,"s":[-4]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":5,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":10,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":13,"s":[-4]},{"t":17.0000006924242,"s":[0]}],"ix":10},"p":{"a":0,"k":[44.581,150.745,0],"ix":2,"l":2},"a":{"a":0,"k":[52.884,15.431,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.98,0.163],[0,0],[-0.163,2.98],[0,0],[-2.98,-0.163],[0,0],[0.163,-2.98],[0,0]],"o":[[0,0],[-2.98,-0.163],[0,0],[0.163,-2.98],[0,0],[2.981,0.163],[0,0],[-0.162,2.98]],"v":[[46.01,15.018],[-47.37,9.925],[-52.471,4.234],[-51.701,-9.916],[-46.01,-15.018],[47.37,-9.925],[52.471,-4.234],[51.699,9.916]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.571013446883,0.408020587996,0.306947476256,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[52.885,15.431],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.000024438501,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"ear Outlines","parent":7,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[16.379,82.609,0],"ix":2,"l":2},"a":{"a":0,"k":[125.561,95.394,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[{"i":[[0,0],[-14.112,-0.01]],"o":[[0,0],[0,0]],"v":[[-9.28,8.852],[16.53,-3.674]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":1,"s":[{"i":[[0,0],[-13.122,-1.378]],"o":[[0,0],[0,0]],"v":[[-7.674,3.916],[17.402,-7.488]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":2,"s":[{"i":[[0,0],[-8.518,10.245]],"o":[[0,0],[0,0]],"v":[[-11.275,-6.334],[14.555,-12.997]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":3,"s":[{"i":[[0,0],[-8.658,11.096]],"o":[[0,0],[0,0]],"v":[[-11.564,-4.009],[14.387,-13.213]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":4,"s":[{"i":[[0,0],[-7.623,13.202]],"o":[[0,0],[0,0]],"v":[[-7.65,14.147],[13.14,-3.872]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":5,"s":[{"i":[[0,0],[-4.14,11.624]],"o":[[0,0],[0,0]],"v":[[0.354,8.414],[10.639,-14.516]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":6,"s":[{"i":[[0,0],[-7.223,9.64]],"o":[[0,0],[0,0]],"v":[[-2.785,5.945],[12.42,-14.646]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":7,"s":[{"i":[[0,0],[-10.774,9.626]],"o":[[0,0],[0,0]],"v":[[-2.371,12.891],[14.215,-8.083]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":8,"s":[{"i":[[0,0],[-13.623,6.657]],"o":[[0,0],[0,0]],"v":[[-4.627,11.641],[13.678,-5.977]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":9,"s":[{"i":[[0,0],[-16.472,3.688]],"o":[[0,0],[0,0]],"v":[[-7.9,7.397],[13.14,-3.872]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":10,"s":[{"i":[[0,0],[-10.493,11.231]],"o":[[0,0],[0,0]],"v":[[-10.036,0.596],[13.73,-6.718]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":11,"s":[{"i":[[0,0],[-12.008,12.259]],"o":[[0,0],[0,0]],"v":[[-11.816,-0.143],[14.418,-9.588]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":12,"s":[{"i":[[0,0],[-7.715,13.833]],"o":[[0,0],[0,0]],"v":[[-7.902,16.91],[13.573,-0.39]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":13,"s":[{"i":[[0,0],[-5.853,15.771]],"o":[[0,0],[0,0]],"v":[[-6.492,19.224],[14.165,-1.047]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":14,"s":[{"i":[[0,0],[-7.918,11.826]],"o":[[0,0],[0,0]],"v":[[1.789,15.826],[14.57,-7.2]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":15,"s":[{"i":[[0,0],[-9.047,7.57]],"o":[[0,0],[0,0]],"v":[[-0.892,13.983],[15.223,-6.025]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":16,"s":[{"i":[[0,0],[-11.58,3.78]],"o":[[0,0],[0,0]],"v":[[-4.086,11.412],[15.877,-4.849]],"c":false}]},{"t":17.0000006924242,"s":[{"i":[[0,0],[-14.112,-0.01]],"o":[[0,0],[0,0]],"v":[[-9.28,8.852],[16.53,-3.674]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.826813222848,0.604634662703,0.378504644656,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":37,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[109.031,99.602],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.000024438501,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":0,"nm":"eye","parent":10,"refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[123.821,32.474,0],"ix":2,"l":2},"a":{"a":0,"k":[540,540,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":1080,"h":1080,"ip":0,"op":600.000024438501,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"mouth Outlines","parent":12,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":4,"s":[2]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":9,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":12,"s":[2]},{"t":17.0000006924242,"s":[0]}],"ix":10},"p":{"a":0,"k":[49.375,55.312,0],"ix":2,"l":2},"a":{"a":0,"k":[53.5,86.159,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[51.717,-13.495],[0,0]],"o":[[0,0],[-0.654,-3.758]],"v":[[-34.188,-10.442],[34.188,23.937]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.786325192919,0.569039737477,0.328715993844,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[160.067,24.187],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-44.928,10.769],[44.928,-10.769]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.933520866843,0.697601737228,0.405795587278,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":107,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[98.428,75.39],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.000024438501,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"lower right leg Outlines","parent":10,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[23.76,71.515,0],"ix":2,"l":2},"a":{"a":0,"k":[128.929,77.5,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[{"i":[[0,0],[40.164,0.144]],"o":[[0,0],[0,0]],"v":[[25.715,-36.562],[-25.715,36.418]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":1,"s":[{"i":[[0,0],[35.642,-5.46]],"o":[[0,0],[0,0]],"v":[[24.652,-37.125],[-18.09,27.355]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":2,"s":[{"i":[[0,0],[27.213,20.273]],"o":[[0,0],[0,0]],"v":[[23.59,-37.687],[-20.881,17.126]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":3,"s":[{"i":[[0,0],[34.147,15.995]],"o":[[0,0],[0,0]],"v":[[22.527,-38.25],[-10.298,18.897]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":4,"s":[{"i":[[0,0],[39.99,9.229]],"o":[[0,0],[0,0]],"v":[[21.464,-38.812],[2.786,28.168]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":5,"s":[{"i":[[0,0],[43.567,-6.222]],"o":[[0,0],[0,0]],"v":[[21.464,-38.812],[27.636,27.818]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":6,"s":[{"i":[[0,0],[36.096,-18.968]],"o":[[0,0],[0,0]],"v":[[21.464,-38.812],[53.861,22.781]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":7,"s":[{"i":[[0,0],[30.388,-23.497]],"o":[[0,0],[0,0]],"v":[[21.464,-38.812],[54.836,25.743]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":8,"s":[{"i":[[0,0],[2.562,-31.259]],"o":[[0,0],[0,0]],"v":[[21.464,-38.812],[79.186,23.706]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":9,"s":[{"i":[[0,0],[-4.01,-31.521]],"o":[[0,0],[0,0]],"v":[[21.464,-38.812],[84.536,22.668]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":10,"s":[{"i":[[0,0],[-35.307,-11.263]],"o":[[0,0],[0,0]],"v":[[22.881,-38.395],[80.286,20.251]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":11,"s":[{"i":[[0,0],[-26.458,-13.63]],"o":[[0,0],[0,0]],"v":[[24.298,-37.979],[65.661,30.96]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":12,"s":[{"i":[[0,0],[-15.26,-18.521]],"o":[[0,0],[0,0]],"v":[[25.714,-37.562],[44.036,40.168]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":13,"s":[{"i":[[0,0],[-16.036,-11.17]],"o":[[0,0],[0,0]],"v":[[25.714,-37.362],[45.586,44.918]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":14,"s":[{"i":[[0,0],[-14.019,-8.193]],"o":[[0,0],[0,0]],"v":[[32.965,-36.412],[18.011,49.293]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":15,"s":[{"i":[[0,0],[10.735,-7.308]],"o":[[0,0],[0,0]],"v":[[30.548,-36.462],[-0.064,43.501]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":16,"s":[{"i":[[0,0],[28.985,-11.166]],"o":[[0,0],[0,0]],"v":[[25.881,-39.012],[-11.389,36.21]],"c":false}]},{"t":17.0000006924242,"s":[{"i":[[0,0],[40.164,0.144]],"o":[[0,0],[0,0]],"v":[[25.715,-36.562],[-25.715,36.418]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.933520866843,0.697601737228,0.405795587278,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":31,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[103.215,114.062],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.000024438501,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"upper right leg Outlines","parent":10,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[231.434,82.78,0],"ix":2,"l":2},"a":{"a":0,"k":[77.5,77.5,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[{"i":[[0,0],[-7.592,-39.184]],"o":[[0,0],[0,0]],"v":[[-32.326,-24],[32.326,24]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":1,"s":[{"i":[[0,0],[-13.489,-51.308]],"o":[[0,0],[0,0]],"v":[[-32.326,-24],[33.076,19.25]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":2,"s":[{"i":[[0,0],[-37.209,-15.804]],"o":[[0,0],[0,0]],"v":[[-32.326,-24],[32.326,24]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":3,"s":[{"i":[[0,0],[-28.737,-21.68]],"o":[[0,0],[0,0]],"v":[[-27.201,-25.625],[14.326,29.25]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":4,"s":[{"i":[[0,0],[-20.265,-27.556]],"o":[[0,0],[0,0]],"v":[[-22.076,-27.25],[-7.674,39.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":5,"s":[{"i":[[0,0],[28.412,-1.107]],"o":[[0,0],[0,0]],"v":[[-26.576,-26],[-50.174,29.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":6,"s":[{"i":[[0,0],[16.666,-20.641]],"o":[[0,0],[0,0]],"v":[[-26.576,-26],[-52.424,38.75]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":7,"s":[{"i":[[0,0],[16.666,-20.641]],"o":[[0,0],[0,0]],"v":[[-26.576,-26],[-52.674,43.75]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":8,"s":[{"i":[[0,0],[24.95,-10.223]],"o":[[0,0],[0,0]],"v":[[-29.201,-26.375],[-62.924,37.125]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":9,"s":[{"i":[[0,0],[33.235,0.194]],"o":[[0,0],[0,0]],"v":[[-31.826,-26.75],[-71.674,34.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":10,"s":[{"i":[[0,0],[30.188,9.285]],"o":[[0,0],[0,0]],"v":[[-33.826,-26.25],[-72.924,25]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":11,"s":[{"i":[[0,0],[34.912,14.876]],"o":[[0,0],[0,0]],"v":[[-33.826,-26.25],[-62.674,23.75]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":12,"s":[{"i":[[0,0],[39.235,14.694]],"o":[[0,0],[0,0]],"v":[[-30.326,-26.25],[-49.674,32.75]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":13,"s":[{"i":[[0,0],[39.509,11.545]],"o":[[0,0],[0,0]],"v":[[-30.326,-26.25],[-49.174,37.25]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":14,"s":[{"i":[[0,0],[41.951,-14.353]],"o":[[0,0],[0,0]],"v":[[-30.326,-26.25],[-24.674,36.75]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":15,"s":[{"i":[[0,0],[37.13,-20.76]],"o":[[0,0],[0,0]],"v":[[-30.326,-26.25],[-0.674,31]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":16,"s":[{"i":[[0,0],[-0.695,-40.16]],"o":[[0,0],[0,0]],"v":[[-30.326,-26.25],[25.326,27.75]],"c":false}]},{"t":17.0000006924242,"s":[{"i":[[0,0],[-7.592,-39.184]],"o":[[0,0],[0,0]],"v":[[-32.326,-24],[32.326,24]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.933520866843,0.697601737228,0.405795587278,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":31,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[109.826,101.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.000024438501,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"body Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[553.572,563.061,0],"to":[0.167,4.333,0],"ti":[-0.167,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":4,"s":[554.572,589.061,0],"to":[0.167,0,0],"ti":[0,0.5,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":9,"s":[554.572,563.061,0],"to":[0,-0.5,0],"ti":[0.167,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":12,"s":[554.572,586.061,0],"to":[-0.167,0,0],"ti":[0.167,3.833,0]},{"t":17.0000006924242,"s":[553.572,563.061,0]}],"ix":2,"l":2},"a":{"a":0,"k":[137.393,55.535,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[30.533,0],[0,0],[0,30.534],[-30.534,0],[0,0],[0,-30.533]],"o":[[0,0],[-30.534,0],[0,-30.533],[0,0],[30.533,0],[0,30.534]],"v":[[81.857,55.285],[-81.857,55.285],[-137.143,-0.001],[-81.857,-55.285],[81.857,-55.285],[137.143,-0.001]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.935039744658,0.697991225299,0.404968740426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[137.393,55.536],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.000024438501,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"tail Outlines","parent":10,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[29.022,32.4,0],"ix":2,"l":2},"a":{"a":0,"k":[93.548,43.783,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[{"i":[[0,0],[-22.285,-11.755],[-14.693,6.51]],"o":[[0,0],[0,0],[0,0]],"v":[[-31.836,3.673],[0.734,1.572],[31.836,3.673]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"t":4,"s":[{"i":[[0,0],[-13.526,-0.602],[-14.693,6.51]],"o":[[0,0],[13.526,0.602],[0,0]],"v":[[-23.836,-4.827],[-3.516,4.072],[33.336,-3.577]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":5,"s":[{"i":[[0,0],[-15.98,15.071],[-19.984,-10.044]],"o":[[0,0],[7.27,-7.179],[0,0]],"v":[[-23.668,7.307],[-1.824,-5.438],[33.18,-2.823]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":6,"s":[{"i":[[0,0],[-17.309,4.778],[-18.286,-4.731]],"o":[[0,0],[16.691,-1.972],[0,0]],"v":[[-28.04,4.141],[-7.252,-11.938],[32.749,-0.737]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"t":7,"s":[{"i":[[0,0],[-18.226,1.637],[-16.738,0.113]],"o":[[0,0],[9.498,-1.122],[0,0]],"v":[[-26.926,10.19],[-3.811,-6.117],[32.356,1.163]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":9,"s":[{"i":[[0,0],[-22.285,-11.755],[-14.693,6.51]],"o":[[0,0],[0,0],[0,0]],"v":[[-31.836,3.673],[0.734,1.572],[31.836,3.673]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"t":12,"s":[{"i":[[0,0],[-13.526,-0.602],[-14.693,6.51]],"o":[[0,0],[13.526,0.602],[0,0]],"v":[[-23.836,-4.827],[-3.516,4.072],[33.336,-3.577]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":14,"s":[{"i":[[0,0],[-15.98,15.071],[-21.249,-2.407]],"o":[[0,0],[7.27,-7.179],[0,0]],"v":[[-24.418,15.807],[-2.574,3.062],[33.18,-2.823]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":15,"s":[{"i":[[0,0],[-17.309,4.778],[-18.286,-4.731]],"o":[[0,0],[16.691,-1.972],[0,0]],"v":[[-27.79,12.391],[-7.002,-3.688],[32.749,-0.737]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"t":16,"s":[{"i":[[0,0],[-17.512,-1.382],[-15.997,2.43]],"o":[[0,0],[6.058,-0.716],[0,0]],"v":[[-28.368,7.587],[-2.074,-0.338],[32.168,2.073]],"c":false}]},{"t":17.0000006924242,"s":[{"i":[[0,0],[-22.285,-11.755],[-14.693,6.51]],"o":[[0,0],[0,0],[0,0]],"v":[[-31.836,3.673],[0.734,1.572],[31.836,3.673]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.623846914254,0.443153381348,0.3248299393,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":12,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[61.836,40.184],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.000024438501,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"neck Outlines","parent":10,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":4,"s":[1]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":9,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":12,"s":[1]},{"t":17.0000006924242,"s":[0]}],"ix":10},"p":{"a":0,"k":[231.679,52.657,0],"ix":2,"l":2},"a":{"a":0,"k":[42.5,211.969,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0.857,-84.734],[-0.857,84.734]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.933520866843,0.697601737228,0.405795587278,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":85,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[43.357,127.234],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.000024438501,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"lower left leg Outlines","parent":10,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[72.25,77.882,0],"ix":2,"l":2},"a":{"a":0,"k":[77.5,77.5,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[{"i":[[0,0],[5.915,-37.794]],"o":[[0,0],[0,0]],"v":[[-25.785,-33.897],[19.87,33.897]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":1,"s":[{"i":[[0,0],[6.067,-37.517]],"o":[[0,0],[0,0]],"v":[[-24.285,-33.772],[19.745,23.96]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":2,"s":[{"i":[[0,0],[-20.695,-9.325]],"o":[[0,0],[0,0]],"v":[[-22.785,-33.647],[16.537,21.522]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":3,"s":[{"i":[[0,0],[-22.594,-14.645]],"o":[[0,0],[0,0]],"v":[[-21.285,-33.522],[7.954,28.085]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":4,"s":[{"i":[[0,0],[-22.585,-19.702]],"o":[[0,0],[0,0]],"v":[[-19.785,-33.397],[-5.63,33.147]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":5,"s":[{"i":[[0,0],[-10.908,-29.003]],"o":[[0,0],[0,0]],"v":[[-19.785,-33.397],[-34.63,39.147]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":6,"s":[{"i":[[0,0],[29.221,-39.037]],"o":[[0,0],[0,0]],"v":[[-29.91,-27.647],[-52.005,32.897]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":7,"s":[{"i":[[0,0],[32.863,-39.103]],"o":[[0,0],[0,0]],"v":[[-40.035,-21.897],[-52.38,38.647]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":8,"s":[{"i":[[0,0],[35.887,-22.153]],"o":[[0,0],[0,0]],"v":[[-40.035,-21.897],[-62.63,31.397]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":9,"s":[{"i":[[0,0],[38.415,-9.702]],"o":[[0,0],[0,0]],"v":[[-40.035,-21.897],[-68.38,29.147]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":10,"s":[{"i":[[0,0],[40.452,0.139]],"o":[[0,0],[0,0]],"v":[[-41.285,-21.98],[-72.213,21.397]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":11,"s":[{"i":[[0,0],[37.759,9.48]],"o":[[0,0],[0,0]],"v":[[-35.035,-19.814],[-63.046,18.897]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":12,"s":[{"i":[[0,0],[39.665,5.798]],"o":[[0,0],[0,0]],"v":[[-28.785,-17.647],[-49.88,28.397]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":13,"s":[{"i":[[0,0],[37.989,7.799]],"o":[[0,0],[0,0]],"v":[[-28.186,-20.897],[-49.43,33.497]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":14,"s":[{"i":[[0,0],[43.356,-10.199]],"o":[[0,0],[0,0]],"v":[[-27.585,-24.147],[-28.105,31.597]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":15,"s":[{"i":[[0,0],[36.044,-21.373]],"o":[[0,0],[0,0]],"v":[[-26.985,-27.397],[-6.113,29.364]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":16,"s":[{"i":[[0,0],[9.227,-42.539]],"o":[[0,0],[0,0]],"v":[[-26.385,-30.647],[14.879,33.13]],"c":false}]},{"t":17.0000006924242,"s":[{"i":[[0,0],[5.915,-37.794]],"o":[[0,0],[0,0]],"v":[[-25.785,-33.897],[19.87,33.897]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.623846914254,0.443153381348,0.3248299393,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":31,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[103.285,111.397],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.000024438501,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"upper left leg Outlines","parent":10,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[218.209,71.515,0],"ix":2,"l":2},"a":{"a":0,"k":[120.91,77.5,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[{"i":[[0,0],[-10.286,67.102]],"o":[[0,0],[0,0]],"v":[[-21.705,35.151],[21.705,-35.151]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":1,"s":[{"i":[[0,0],[-4.049,63.77]],"o":[[0,0],[0,0]],"v":[[-22.392,27.714],[15.642,-35.464]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":2,"s":[{"i":[[0,0],[-8.707,70.503]],"o":[[0,0],[0,0]],"v":[[-25.747,19.026],[14.58,-35.443]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":3,"s":[{"i":[[0,0],[9.373,75.225]],"o":[[0,0],[0,0]],"v":[[-15.601,19.964],[13.517,-35.422]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":4,"s":[{"i":[[0,0],[28.612,77.209]],"o":[[0,0],[0,0]],"v":[[-2.455,29.401],[12.455,-35.401]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":5,"s":[{"i":[[0,0],[47.389,61.509]],"o":[[0,0],[0,0]],"v":[[18.345,29.401],[13.355,-35.501]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":6,"s":[{"i":[[0,0],[72.493,54.825]],"o":[[0,0],[0,0]],"v":[[34.77,27.776],[14.255,-35.601]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":7,"s":[{"i":[[0,0],[66.61,54.109]],"o":[[0,0],[0,0]],"v":[[37.528,32.318],[15.155,-35.701]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":8,"s":[{"i":[[0,0],[59.236,39.659]],"o":[[0,0],[0,0]],"v":[[60.287,36.61],[16.055,-35.801]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":9,"s":[{"i":[[0,0],[51.862,25.209]],"o":[[0,0],[0,0]],"v":[[64.045,36.901],[16.955,-35.901]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":10,"s":[{"i":[[0,0],[17.315,47.05]],"o":[[0,0],[0,0]],"v":[[62.045,31.401],[16.955,-35.901]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":11,"s":[{"i":[[0,0],[11.289,49.892]],"o":[[0,0],[0,0]],"v":[[53.795,37.151],[16.955,-35.901]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":12,"s":[{"i":[[0,0],[-2.138,49.709]],"o":[[0,0],[0,0]],"v":[[41.545,42.901],[16.955,-35.901]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":13,"s":[{"i":[[0,0],[5.186,59.16]],"o":[[0,0],[0,0]],"v":[[40.395,46.352],[17.905,-35.751]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":14,"s":[{"i":[[0,0],[-34.072,66.112]],"o":[[0,0],[0,0]],"v":[[12.37,50.051],[31.355,-30.101]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":15,"s":[{"i":[[0,0],[-20.176,70.388]],"o":[[0,0],[0,0]],"v":[[-5.488,45.085],[23.638,-27.285]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":16,"s":[{"i":[[0,0],[-14.535,63.422]],"o":[[0,0],[0,0]],"v":[[-16.097,37.618],[22.672,-31.218]],"c":false}]},{"t":17.0000006924242,"s":[{"i":[[0,0],[-10.286,67.102]],"o":[[0,0],[0,0]],"v":[[-21.705,35.151],[21.705,-35.151]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.623846914254,0.443153381348,0.3248299393,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":31,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[99.205,112.652],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.000024438501,"st":0,"ct":1,"bm":0}]},{"id":"comp_1","nm":"eye","fr":29.9700012207031,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"eye Outlines 2","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[659.98,361.286,0],"ix":2,"l":2},"a":{"a":0,"k":[32.148,32.148,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-4.328],[4.328,0],[0,4.328],[-4.328,0]],"o":[[0,4.328],[-4.328,0],[0,-4.328],[4.328,0]],"v":[[7.837,0],[-0.001,7.837],[-7.837,0],[-0.001,-7.837]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203373763141,0.203600565592,0.203484329523,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[52.352,28.76],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-17.617],[17.617,0],[0,17.617],[-17.617,0]],"o":[[0,17.617],[-17.617,0],[0,-17.617],[17.617,0]],"v":[[31.898,0],[0,31.898],[-31.898,0],[0,-31.898]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.999998743394,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[32.148,32.148],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.000024438501,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 1","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,540,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":5,"s":[{"i":[[36.5,-10],[0,0],[0,0]],"o":[[-36.5,10],[0,0],[0,0]],"v":[[106,-257.5],[72,-176.5],[170.5,-194.5]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":8.294,"s":[{"i":[[36.5,-10],[-65.5,-87.5],[12,37]],"o":[[-36.5,10],[51.5,82.5],[-8.805,-27.147]],"v":[[106,-257.5],[61.5,-172],[170.5,-194.5]],"c":true}]},{"t":12.00000048877,"s":[{"i":[[36.5,-10],[0,0],[0,0]],"o":[[-36.5,10],[0,0],[0,0]],"v":[[106,-257.5],[72,-176.5],[170.5,-194.5]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333333333,0.698039215686,0.403921568627,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.000024438501,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"eye Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[659.98,361.286,0],"ix":2,"l":2},"a":{"a":0,"k":[32.148,32.148,0],"ix":1,"l":2},"s":{"a":0,"k":[98,98,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-4.328],[4.328,0],[0,4.328],[-4.328,0]],"o":[[0,4.328],[-4.328,0],[0,-4.328],[4.328,0]],"v":[[7.837,0],[-0.001,7.837],[-7.837,0],[-0.001,-7.837]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203373763141,0.203600565592,0.203484329523,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[52.352,28.76],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-17.617],[17.617,0],[0,17.617],[-17.617,0]],"o":[[0,17.617],[-17.617,0],[0,-17.617],[17.617,0]],"v":[[31.898,0],[0,31.898],[-31.898,0],[0,-31.898]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.999998743394,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[32.148,32.148],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.000024438501,"st":0,"ct":1,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"1","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[504,592,0],"ix":2,"l":2},"a":{"a":0,"k":[540,540,0],"ix":1,"l":2},"s":{"a":0,"k":[146,146,100],"ix":6,"l":2}},"ao":0,"w":1080,"h":1080,"ip":0,"op":600.000024438501,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryImageView.axaml b/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryImageView.axaml index 4dd4f029f..56e8c8670 100644 --- a/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryImageView.axaml +++ b/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryImageView.axaml @@ -7,18 +7,25 @@ mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Artemis.UI.Screens.Workshop.Entries.Details.EntryImageView" x:DataType="details:EntryImageViewModel"> - + - - - - - - + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryImageViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryImageViewModel.cs index 5bfaa1052..1676a58b1 100644 --- a/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryImageViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryImageViewModel.cs @@ -1,8 +1,9 @@ -using Artemis.WebClient.Workshop; +using Artemis.UI.Shared; +using Artemis.WebClient.Workshop; namespace Artemis.UI.Screens.Workshop.Entries.Details; -public class EntryImageViewModel +public class EntryImageViewModel : ViewModelBase { public EntryImageViewModel(IImage image) { diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryImagesView.axaml b/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryImagesView.axaml index 3c7168cde..e4af87004 100644 --- a/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryImagesView.axaml +++ b/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryImagesView.axaml @@ -8,21 +8,23 @@ mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Artemis.UI.Screens.Workshop.Entries.Details.EntryImagesView" x:DataType="details:EntryImagesViewModel"> - - - - - - - - - - - - - - + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/Entries/EntriesView.axaml b/src/Artemis.UI/Screens/Workshop/Entries/EntriesView.axaml index ecc131eb9..a68969ec2 100644 --- a/src/Artemis.UI/Screens/Workshop/Entries/EntriesView.axaml +++ b/src/Artemis.UI/Screens/Workshop/Entries/EntriesView.axaml @@ -23,7 +23,7 @@ - + diff --git a/src/Artemis.UI/Screens/Workshop/Image/ImagePropertiesDialogView.axaml.cs b/src/Artemis.UI/Screens/Workshop/Image/ImagePropertiesDialogView.axaml.cs index 5c47dd4c4..5fff5fc55 100644 --- a/src/Artemis.UI/Screens/Workshop/Image/ImagePropertiesDialogView.axaml.cs +++ b/src/Artemis.UI/Screens/Workshop/Image/ImagePropertiesDialogView.axaml.cs @@ -1,10 +1,11 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Markup.Xaml; +using Avalonia.ReactiveUI; namespace Artemis.UI.Screens.Workshop.Image; -public partial class ImagePropertiesDialogView : UserControl +public partial class ImagePropertiesDialogView : ReactiveUserControl { public ImagePropertiesDialogView() { diff --git a/src/Artemis.UI/Screens/Workshop/Image/ImageSubmissionView.axaml b/src/Artemis.UI/Screens/Workshop/Image/ImageSubmissionView.axaml index 8a880f46f..04d4b10de 100644 --- a/src/Artemis.UI/Screens/Workshop/Image/ImageSubmissionView.axaml +++ b/src/Artemis.UI/Screens/Workshop/Image/ImageSubmissionView.axaml @@ -21,7 +21,7 @@ Source="{CompiledBinding Bitmap}" /> - + - diff --git a/src/Artemis.UI/Screens/Workshop/Image/ImageSubmissionViewModel.cs b/src/Artemis.UI/Screens/Workshop/Image/ImageSubmissionViewModel.cs index 1b3c15962..3d403c628 100644 --- a/src/Artemis.UI/Screens/Workshop/Image/ImageSubmissionViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Image/ImageSubmissionViewModel.cs @@ -4,13 +4,14 @@ using System.Threading.Tasks; using System.Windows.Input; using Artemis.UI.Shared; using Artemis.UI.Shared.Services; -using Artemis.UI.Shared.Services.Builders; using Artemis.WebClient.Workshop.Handlers.UploadHandlers; using Avalonia.Media.Imaging; using Avalonia.Threading; +using FluentAvalonia.UI.Controls; using PropertyChanged.SourceGenerator; using ReactiveUI; using ReactiveUI.Validation.Extensions; +using ContentDialogButton = Artemis.UI.Shared.Services.Builders.ContentDialogButton; namespace Artemis.UI.Screens.Workshop.Image; @@ -30,30 +31,35 @@ public partial class ImageSubmissionViewModel : ValidatableViewModelBase _image = image; _windowService = windowService; + FileSize = _image.File.Length; + Name = _image.Name; + Description = _image.Description; + this.WhenActivated(d => { Dispatcher.UIThread.Invoke(() => { _image.File.Seek(0, SeekOrigin.Begin); Bitmap = new Bitmap(_image.File); - FileSize = _image.File.Length; ImageDimensions = Bitmap.Size.Width + "x" + Bitmap.Size.Height; - Name = _image.Name; - Description = _image.Description; - Bitmap.DisposeWith(d); }, DispatcherPriority.Background); }); } - public async Task Edit() + public async Task Edit() { - await _windowService.CreateContentDialog() + ContentDialogResult result = await _windowService.CreateContentDialog() .WithTitle("Edit image properties") .WithViewModel(out ImagePropertiesDialogViewModel vm, _image) .HavingPrimaryButton(b => b.WithText("Confirm").WithCommand(vm.Confirm)) .WithCloseButtonText("Cancel") .WithDefaultButton(ContentDialogButton.Primary) .ShowAsync(); + + Name = _image.Name; + Description = _image.Description; + + return result; } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/Library/SubmissionDetailViewModel.cs b/src/Artemis.UI/Screens/Workshop/Library/SubmissionDetailViewModel.cs index e2acea559..a70e014a0 100644 --- a/src/Artemis.UI/Screens/Workshop/Library/SubmissionDetailViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Library/SubmissionDetailViewModel.cs @@ -158,7 +158,7 @@ public partial class SubmissionDetailViewModel : RoutableScreen(), stream, cancellationToken); + ImageUploadResult imageResult = await _workshopService.SetEntryIcon(Entry.Id, stream, cancellationToken); if (!imageResult.IsSuccess) throw new ArtemisWorkshopException("Failed to upload image. " + imageResult.Message); } diff --git a/src/Artemis.UI/Screens/Workshop/Profile/ProfileDetailsView.axaml b/src/Artemis.UI/Screens/Workshop/Profile/ProfileDetailsView.axaml index af516a4f0..0569ee176 100644 --- a/src/Artemis.UI/Screens/Workshop/Profile/ProfileDetailsView.axaml +++ b/src/Artemis.UI/Screens/Workshop/Profile/ProfileDetailsView.axaml @@ -8,7 +8,7 @@ x:Class="Artemis.UI.Screens.Workshop.Profile.ProfileDetailsView" x:DataType="profile:ProfileDetailsViewModel"> - + @@ -17,7 +17,7 @@ - + @@ -25,8 +25,6 @@ - - - + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/ImagesStepViewModel.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/ImagesStepViewModel.cs index 2a430347f..3efdb1259 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/ImagesStepViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/ImagesStepViewModel.cs @@ -9,6 +9,7 @@ using Artemis.UI.Screens.Workshop.Image; using Artemis.UI.Shared.Services; using Artemis.WebClient.Workshop.Handlers.UploadHandlers; using DynamicData; +using FluentAvalonia.UI.Controls; using ReactiveUI; namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps; @@ -49,7 +50,7 @@ public class ImagesStepViewModel : SubmissionViewModel private ImageSubmissionViewModel CreateImageSubmissionViewModel(ImageUploadRequest image) { ImageSubmissionViewModel viewModel = _getImageSubmissionViewModel(image); - viewModel.Remove = ReactiveCommand.Create(() => _stateImages.Remove(image)); + viewModel.Remove = ReactiveCommand.Create(() => RemoveImage(image)); return viewModel; } @@ -73,8 +74,23 @@ public class ImagesStepViewModel : SubmissionViewModel } ImageUploadRequest request = new(stream, Path.GetFileName(path), string.Empty); - _stateImages.Add(request); - State.Images.Add(request); + AddImage(request); + + // Show the dialog to give the image a name and description + if (await Images.Last().Edit() != ContentDialogResult.Primary) + RemoveImage(request); // user did not click confirm, remove again } } + + private void AddImage(ImageUploadRequest image) + { + _stateImages.Add(image); + State.Images.Add(image); + } + + private void RemoveImage(ImageUploadRequest image) + { + _stateImages.Remove(image); + State.Images.Remove(image); + } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/UploadStepView.axaml b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/UploadStepView.axaml index e3b9e23c3..7473b4714 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/UploadStepView.axaml +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/UploadStepView.axaml @@ -16,17 +16,11 @@ - - Uploading your submission... - - - - - + + + Uploading your submission... + + All done! Hit finish to view your submission. diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/UploadStepViewModel.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/UploadStepViewModel.cs index bf6c4f395..80de21f1d 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/UploadStepViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/UploadStepViewModel.cs @@ -23,9 +23,6 @@ public partial class UploadStepViewModel : SubmissionViewModel { private readonly ILogger _logger; private readonly EntryUploadHandlerFactory _entryUploadHandlerFactory; - private readonly Progress _progress = new(); - private readonly ObservableAsPropertyHelper _progressIndeterminate; - private readonly ObservableAsPropertyHelper _progressPercentage; private readonly IRouter _router; private readonly IWindowService _windowService; private readonly IWorkshopClient _workshopClient; @@ -40,7 +37,7 @@ public partial class UploadStepViewModel : SubmissionViewModel IWorkshopClient workshopClient, IWorkshopService workshopService, EntryUploadHandlerFactory entryUploadHandlerFactory, - IWindowService windowService, + IWindowService windowService, IRouter router) { _logger = logger; @@ -54,19 +51,9 @@ public partial class UploadStepViewModel : SubmissionViewModel ContinueText = "Finish"; Continue = ReactiveCommand.CreateFromTask(ExecuteContinue, this.WhenAnyValue(vm => vm.Finished)); - _progressPercentage = Observable.FromEventPattern(x => _progress.ProgressChanged += x, x => _progress.ProgressChanged -= x) - .Select(e => e.EventArgs.ProgressPercentage) - .ToProperty(this, vm => vm.ProgressPercentage); - _progressIndeterminate = Observable.FromEventPattern(x => _progress.ProgressChanged += x, x => _progress.ProgressChanged -= x) - .Select(e => e.EventArgs.ProgressPercentage == 0) - .ToProperty(this, vm => vm.ProgressIndeterminate); - this.WhenActivated(d => Observable.FromAsync(ExecuteUpload).Subscribe().DisposeWith(d)); } - public int ProgressPercentage => _progressPercentage.Value; - public bool ProgressIndeterminate => _progressIndeterminate.Value; - private async Task ExecuteUpload(CancellationToken cancellationToken) { // Use the existing entry or create a new one @@ -79,7 +66,7 @@ public partial class UploadStepViewModel : SubmissionViewModel try { IEntryUploadHandler uploadHandler = _entryUploadHandlerFactory.CreateHandler(State.EntryType); - EntryUploadResult uploadResult = await uploadHandler.CreateReleaseAsync(_entryId.Value, State.EntrySource!, _progress, cancellationToken); + EntryUploadResult uploadResult = await uploadHandler.CreateReleaseAsync(_entryId.Value, State.EntrySource!, cancellationToken); if (!uploadResult.IsSuccess) { string? message = uploadResult.Message; @@ -96,7 +83,7 @@ public partial class UploadStepViewModel : SubmissionViewModel catch (Exception e) { _logger.Error(e, "Failed to upload submission for entry {EntryId}", _entryId); - + // Something went wrong when creating a release :c // We'll keep the workshop entry so that the user can make changes and try again Failed = true; @@ -109,6 +96,8 @@ public partial class UploadStepViewModel : SubmissionViewModel private async Task CreateEntry(CancellationToken cancellationToken) { + await Task.Delay(2000); + IOperationResult result = await _workshopClient.AddEntry.ExecuteAsync(new CreateEntryInput { EntryType = State.EntryType, @@ -122,57 +111,40 @@ public partial class UploadStepViewModel : SubmissionViewModel long? entryId = result.Data?.AddEntry?.Id; if (result.IsErrorResult() || entryId == null) { - await _windowService.ShowConfirmContentDialog("Failed to create workshop entry", string.Join("\r\n", result.Errors.Select(e => e.Message)), "Close", null); - State.ChangeScreen(); - return null; - } - - if (cancellationToken.IsCancellationRequested) - { + await _windowService.ShowConfirmContentDialog("Failed to create workshop entry", string.Join("\r\n", result.Errors.Select(e => e.Message)), "Close", null); State.ChangeScreen(); return null; } + cancellationToken.ThrowIfCancellationRequested(); foreach (ImageUploadRequest image in State.Images.ToList()) { - // Upload image - try - { - ImageUploadResult imageUploadResult = await _workshopService.UploadEntryImage(entryId.Value, image, _progress, cancellationToken); - if (!imageUploadResult.IsSuccess) - throw new ArtemisWorkshopException(imageUploadResult.Message); - State.Images.Remove(image); - } - catch (Exception e) - { - // It's not critical if this fails - await _windowService.ShowConfirmContentDialog("Failed to upload image", "Your submission will continue, you can try upload a new image afterwards\r\n" + e.Message, "Continue", null); - } - - if (cancellationToken.IsCancellationRequested) - { - State.ChangeScreen(); - return null; - } + await TryImageUpload(async () => await _workshopService.UploadEntryImage(entryId.Value, image, cancellationToken)); + cancellationToken.ThrowIfCancellationRequested(); } if (State.Icon == null) return entryId; // Upload icon + await TryImageUpload(async () => await _workshopService.SetEntryIcon(entryId.Value, State.Icon, cancellationToken)); + + return entryId; + } + + private async Task TryImageUpload(Func> action) + { try { - ImageUploadResult imageUploadResult = await _workshopService.SetEntryIcon(entryId.Value, _progress, State.Icon, cancellationToken); - if (!imageUploadResult.IsSuccess) - throw new ArtemisWorkshopException(imageUploadResult.Message); + ImageUploadResult result = await action(); + if (!result.IsSuccess) + throw new ArtemisWorkshopException(result.Message); } catch (Exception e) { // It's not critical if this fails - await _windowService.ShowConfirmContentDialog("Failed to upload icon", "Your submission will continue, you can try upload a new image afterwards\r\n" + e.Message, "Continue", null); + await _windowService.ShowConfirmContentDialog("Failed to upload", "Your submission will continue, you can try upload a new image afterwards\r\n" + e.Message, "Continue", null); } - - return entryId; } private async Task ExecuteContinue() diff --git a/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/IEntryUploadHandler.cs b/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/IEntryUploadHandler.cs index b391dd963..c0bc829be 100644 --- a/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/IEntryUploadHandler.cs +++ b/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/IEntryUploadHandler.cs @@ -4,5 +4,5 @@ namespace Artemis.WebClient.Workshop.Handlers.UploadHandlers; public interface IEntryUploadHandler { - Task CreateReleaseAsync(long entryId, IEntrySource entrySource, Progress progress, CancellationToken cancellationToken); + Task CreateReleaseAsync(long entryId, IEntrySource entrySource, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/LayoutEntryUploadHandler.cs b/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/LayoutEntryUploadHandler.cs index 2e16a085e..e30bb2474 100644 --- a/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/LayoutEntryUploadHandler.cs +++ b/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/LayoutEntryUploadHandler.cs @@ -19,7 +19,7 @@ public class LayoutEntryUploadHandler : IEntryUploadHandler } /// - public async Task CreateReleaseAsync(long entryId, IEntrySource entrySource, Progress progress, CancellationToken cancellationToken) + public async Task CreateReleaseAsync(long entryId, IEntrySource entrySource, CancellationToken cancellationToken) { if (entrySource is not LayoutEntrySource source) throw new InvalidOperationException("Can only create releases for layouts"); @@ -67,7 +67,7 @@ public class LayoutEntryUploadHandler : IEntryUploadHandler // Construct the request MultipartFormDataContent content = new(); - ProgressableStreamContent streamContent = new(archiveStream, progress); + StreamContent streamContent = new(archiveStream); streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/zip"); content.Add(streamContent, "file", "file.zip"); diff --git a/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/ProfileEntryUploadHandler.cs b/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/ProfileEntryUploadHandler.cs index 9466cb92e..e5a5fa961 100644 --- a/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/ProfileEntryUploadHandler.cs +++ b/src/Artemis.WebClient.Workshop/Handlers/UploadHandlers/Implementations/ProfileEntryUploadHandler.cs @@ -18,7 +18,7 @@ public class ProfileEntryUploadHandler : IEntryUploadHandler } /// - public async Task CreateReleaseAsync(long entryId, IEntrySource entrySource, Progress progress, CancellationToken cancellationToken) + public async Task CreateReleaseAsync(long entryId, IEntrySource entrySource, CancellationToken cancellationToken) { if (entrySource is not ProfileEntrySource source) throw new InvalidOperationException("Can only create releases for profile configurations"); @@ -30,7 +30,7 @@ public class ProfileEntryUploadHandler : IEntryUploadHandler // Construct the request MultipartFormDataContent content = new(); - ProgressableStreamContent streamContent = new(archiveStream, progress); + StreamContent streamContent = new(archiveStream); streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/zip"); content.Add(streamContent, "file", "file.zip"); diff --git a/src/Artemis.WebClient.Workshop/Services/Interfaces/IWorkshopService.cs b/src/Artemis.WebClient.Workshop/Services/Interfaces/IWorkshopService.cs index 67dd4d310..f1041f2d0 100644 --- a/src/Artemis.WebClient.Workshop/Services/Interfaces/IWorkshopService.cs +++ b/src/Artemis.WebClient.Workshop/Services/Interfaces/IWorkshopService.cs @@ -6,8 +6,8 @@ namespace Artemis.WebClient.Workshop.Services; public interface IWorkshopService { Task GetEntryIcon(long entryId, CancellationToken cancellationToken); - Task SetEntryIcon(long entryId, Progress progress, Stream icon, CancellationToken cancellationToken); - Task UploadEntryImage(long entryId, ImageUploadRequest request, Progress progress, CancellationToken cancellationToken); + Task SetEntryIcon(long entryId, Stream icon, CancellationToken cancellationToken); + Task UploadEntryImage(long entryId, ImageUploadRequest request, CancellationToken cancellationToken); Task GetWorkshopStatus(CancellationToken cancellationToken); Task ValidateWorkshopStatus(CancellationToken cancellationToken); Task NavigateToEntry(long entryId, EntryType entryType); diff --git a/src/Artemis.WebClient.Workshop/Services/WorkshopService.cs b/src/Artemis.WebClient.Workshop/Services/WorkshopService.cs index 1542de657..3257c5c0e 100644 --- a/src/Artemis.WebClient.Workshop/Services/WorkshopService.cs +++ b/src/Artemis.WebClient.Workshop/Services/WorkshopService.cs @@ -36,7 +36,7 @@ public class WorkshopService : IWorkshopService } } - public async Task SetEntryIcon(long entryId, Progress progress, Stream icon, CancellationToken cancellationToken) + public async Task SetEntryIcon(long entryId, Stream icon, CancellationToken cancellationToken) { icon.Seek(0, SeekOrigin.Begin); @@ -45,7 +45,7 @@ public class WorkshopService : IWorkshopService // Construct the request MultipartFormDataContent content = new(); - ProgressableStreamContent streamContent = new(icon, progress); + StreamContent streamContent = new(icon); streamContent.Headers.ContentType = new MediaTypeHeaderValue("image/png"); content.Add(streamContent, "file", "file.png"); @@ -57,7 +57,7 @@ public class WorkshopService : IWorkshopService } /// - public async Task UploadEntryImage(long entryId, ImageUploadRequest request, Progress progress, CancellationToken cancellationToken) + public async Task UploadEntryImage(long entryId, ImageUploadRequest request, CancellationToken cancellationToken) { request.File.Seek(0, SeekOrigin.Begin); @@ -66,7 +66,7 @@ public class WorkshopService : IWorkshopService // Construct the request MultipartFormDataContent content = new(); - ProgressableStreamContent streamContent = new(request.File, progress); + StreamContent streamContent = new(request.File); streamContent.Headers.ContentType = new MediaTypeHeaderValue("image/png"); content.Add(streamContent, "file", "file.png"); content.Add(new StringContent(request.Name), "Name");