Submission wizard - Added Lottie animations and the first few steps

This commit is contained in:
Robert committed 2023-08-09 11:54:35 +02:00
1 parent 661242ebf9
commit 78cb95aabc
29 files changed
+534 -153

No files matched your search

+1
View File
@@ -24,6 +24,7 @@
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="$(AvaloniaVersion)" />
<PackageReference Include="Avalonia.ReactiveUI" Version="$(AvaloniaVersion)" />
<PackageReference Include="Avalonia.Skia.Lottie" Version="11.0.0" />
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="$(AvaloniaVersion)" />
<PackageReference Include="DryIoc.dll" Version="5.4.0" />
<PackageReference Include="DynamicData" Version="7.13.1" />
@@ -0,0 +1 @@
{"v":"5.7.1","fr":25,"ip":0,"op":200,"w":1000,"h":1000,"nm":"Work frome Home Mailing F","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 1","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[500,652,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":200,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"mail 4","parent":1,"td":1,"sr":1,"ks":{"o":{"a":0,"k":99,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[183.055,-315.211,0],"ix":2},"a":{"a":0,"k":[2153.478,680.843,0],"ix":1},"s":{"a":0,"k":[56,56,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.758,-2.403],[0,0],[0,0],[0,0],[-21.953,-7.476],[-0.627,-0.393]],"o":[[0,0],[0,0],[0,0],[0,0],[9.299,3.167],[1.978,1.239]],"v":[[78.735,-34.708],[80.678,-28.718],[-58.964,72.319],[-68.916,40.154],[58.006,-46.114],[74.435,-40.273]],"c":true},"ix":2},"nm":"Path 4","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.174548238516,0.452203959227,0.890196084976,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 3","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1801.139,934.164],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[594,594],"ix":3},"r":{"a":0,"k":17.3,"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":"back 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":204,"st":-23,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"plane 2","parent":1,"tt":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-30.27,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.57,"y":1},"o":{"x":0.43,"y":0},"t":0,"s":[-417.664,54.901,0],"to":[29.664,67.099,0],"ti":[8.659,75.131,0]},{"i":{"x":0.57,"y":1},"o":{"x":0.444,"y":0},"t":50,"s":[384.659,-254.869,0],"to":[-6.219,-53.959,0],"ti":[-29.664,-67.099,0]},{"i":{"x":0.57,"y":1},"o":{"x":0.43,"y":0},"t":100,"s":[-417.664,54.901,0],"to":[29.664,67.099,0],"ti":[8.659,75.131,0]},{"i":{"x":0.595,"y":1},"o":{"x":0.444,"y":0},"t":150,"s":[384.659,-254.869,0],"to":[-6.219,-53.959,0],"ti":[-17.336,-57.901,0]},{"t":199,"s":[-417.664,54.901,0]}],"ix":2},"a":{"a":0,"k":[816.438,755.113,0],"ix":1},"s":{"a":0,"k":[65,65,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":-7,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[18.514,-6.941],[-33.276,21.927],[93.386,-0.562]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"t":3,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-6.915,-14.251],[-9.38,40.839],[47.51,-30.24]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"t":12,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[21.986,-29.805],[113.019,32.241],[42.547,-64.73]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-0.528,-14.328],[129.556,-5.673],[-49.243,-49.537]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":48,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[12.419,-8.39],[20.033,-35.22],[-88.885,-12.543]],"c":true}]},{"i":{"x":0.32,"y":1},"o":{"x":0.167,"y":0.167},"t":61,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[55.573,8.709],[-40.935,-18.354],[28.444,45.375]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"t":70,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[6.11,3.203],[-110.008,-19.184],[7.061,50.133]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"t":84,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[70.462,-13.025],[-68.13,-5.656],[131.7,43.826]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":93,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[18.514,-6.941],[-33.276,21.927],[93.387,-0.562]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"t":103,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-6.915,-14.251],[-9.38,40.839],[47.51,-30.24]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"t":112,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[21.986,-29.805],[113.019,32.241],[42.547,-64.73]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":130,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-0.528,-14.328],[129.556,-5.673],[-49.243,-49.537]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":148,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[12.419,-8.39],[20.033,-35.22],[-88.885,-12.543]],"c":true}]},{"i":{"x":0.32,"y":1},"o":{"x":0.167,"y":0.167},"t":161,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[55.573,8.709],[-40.935,-18.354],[28.444,45.375]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"t":170,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[Line truncated
@@ -0,0 +1 @@
{"nm":"IdenityVerificationPending","ddd":0,"h":640,"w":640,"meta":{"g":"@lottiefiles/toolkit-js 0.26.1"},"layers":[{"ty":3,"nm":"Null 5","sr":1,"st":0,"op":120.0000048877,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[50,50,0],"ix":1},"s":{"a":0,"k":[375,375,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[323.75,325,0],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":0,"k":0,"ix":11}},"ef":[],"ind":1},{"ty":4,"nm":"Layer 2 Outlines","sr":1,"st":-16.0000006516934,"op":120.0000048877,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[29.338,24.542,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[49,48.95,0],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":0,"k":100,"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Group 1","ix":1,"cix":2,"np":2,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":true,"i":[[2.303,0],[0,0],[0,2.303],[0,0],[-2.303,0],[0,0],[0,-2.303],[0,0]],"o":[[0,0],[-2.303,0],[0,0],[0,-2.303],[0,0],[2.303,0],[0,0],[0,2.303]],"v":[[17.667,17.042],[-17.667,17.042],[-21.837,12.872],[-21.837,-12.872],[-17.667,-17.042],[17.667,-17.042],[21.837,-12.872],[21.837,12.872]]},"ix":2}},{"ty":"st","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":1,"lj":1,"ml":10,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"c":{"a":0,"k":[1,1,1],"ix":3}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[29.338,24.542],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":2,"parent":1},{"ty":4,"nm":"Layer 7 Outlines","sr":1,"st":-16.0000006516934,"op":120.0000048877,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0.527,1.53,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[54.387,42.54,0],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":0,"k":100,"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Group 1","ix":1,"cix":2,"np":2,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,-0.35],[0,0],[0.36,0],[0,0],[0,0.35],[0,0],[-0.35,0],[0,0]],"o":[[0,0],[0,0.35],[0,0],[-0.35,0],[0,0],[0,-0.35],[0,0],[0.36,0]],"v":[[5.11,-0.64],[5.11,0.64],[4.47,1.28],[-4.47,1.28],[-5.11,0.64],[-5.11,-0.64],[-4.47,-1.28],[4.47,-1.28]]},"ix":2}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0.451,0.8471,0.7765],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[5.36,1.53],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":3,"parent":1},{"ty":4,"nm":"Layer 6 Outlines","sr":1,"st":-16.0000006516934,"op":120.0000048877,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[10.36,1.53,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[64.22,47.67,0],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":0,"k":100,"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Group 1","ix":1,"cix":2,"np":2,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,-0.35],[0,0],[0.36,0],[0,0],[0,0.35],[0,0],[-0.35,0],[0,0]],"o":[[0,0],[0,0.35],[0,0],[-0.35,0],[0,0],[0,-0.35],[0,0],[0.36,0]],"v":[[5.11,-0.64],[5.11,0.64],[4.47,1.28],[-4.47,1.28],[-5.11,0.64],[-5.11,-0.64],[-4.47,-1.28],[4.47,-1.28]]},"ix":2}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[1,1,1],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[5.36,1.53],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":4,"parent":1},{"ty":4,"nm":"Layer 5 Outlines","sr":1,"st":-16.0000006516934,"op":120.0000048877,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0.527,1.53,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[54.387,52.8,0],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":0,"k":100,"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Group 1","ix":1,"cix":2,"np":2,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,-0.36],[0,0],[0.36,0],[0,0],[0,0.35],[0,0],[-0.35,0],[0,0]],"o":[[0,0],[0,0.35],[0,0],[-0.35,0],[0,0],[0,-0.36],[0,0],[0.36,0]],"v":[[5.11,-0.64],[5.11,0.64],[4.47,1.28],[-4.47,1.28],[-5.11,0.64],[-5.11,-0.64],[-Line truncated
@@ -0,0 +1 @@
{"v":"5.7.8","fr":30,"ip":0,"op":301,"w":300,"h":300,"nm":"free 04","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 9","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[150,170,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[191,191,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":301,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shapes on screen 2","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-26,94.218,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":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0.762],[0.762,0],[0,-0.762],[-0.762,0]],"o":[[0,-0.762],[-0.762,0],[0,0.762],[0.762,0]],"v":[[40.188,-146.941],[38.809,-148.32],[37.429,-146.941],[38.809,-145.561]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0.762],[-0.762,0],[0,-0.762],[0.762,0]],"o":[[0,-0.762],[0.762,0],[0,0.762],[-0.762,0]],"v":[[15.077,-146.941],[16.457,-148.32],[17.836,-146.941],[16.457,-145.561]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.807843148708,0.827450990677,0.972549021244,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":"Group 4","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[11.008,-159.04],[6.02,-164.027]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[9.345,-152.39],[2.695,-152.39]],"c":false},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":103,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":107,"s":[0]},{"t":113,"s":[100],"h":1},{"t":130,"s":[0],"h":1},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":250,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":254,"s":[0]},{"t":260,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":103,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":107,"s":[100]},{"t":113,"s":[100],"h":1},{"t":130,"s":[0],"h":1},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":250,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":254,"s":[100]},{"t":260,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.988235294819,0.729411780834,0.023529412225,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":2,"lj":2,"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":"Group 1","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","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":"Group 5","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[27.633,-136.939],[27.633,-133.004]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.258823543787,0.243137255311,0.686274528503,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":2,"lj":2,"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":"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,-1.894],[1.894,0],[0,1.894],[-1.894,0]],"o":[[0,1.894],[-1.894,0],[0,-1.894],[1.894,0]],"v":[[31.062,-139.433],[27.633,-136.003],[24.203,-139.433],[27.633,-142.862]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},Line truncated
@@ -0,0 +1 @@
{"v": "5.5.7", "meta": {"g": "LottieFiles AE 0.1.20", "a": "", "k": "", "d": "", "tc": ""}, "fr": 24, "ip": 0, "op": 36, "w": 1600, "h": 1200, "nm": "graphic", "ddd": 0, "assets": [{"id": "image_0", "w": 163, "h": 319, "u": "", "p": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKMAAAE/CAYAAAAqv3MMAAAgAElEQVR4Xu19a4xd13XeWmcoinLRSrVsaeYOVbk/CgRIC7m/8qMFpF+FESC2GjQ/UgQQlaZAAzsWhbSO7cTVOI6rSCQ1M/cxVCjHJEWbD/lBWX7bskRZsixZb9mJLNoW9eSMXqYoW5y5r72KtR/n7nPued73ubMHGHBmeO5j9vlm7b2+b61vIbiPTbMCh3e/ejUAXA1E7yeAK4gACADMv0LACwR4og3iwP/8xNyJUS8MjvoF3euNdgWOL565aKO1sRMQdwLAhQZ4/C6EDUbqfM8/FwQvCKCFP//ruQOjescOjKNa6RG/jgSh2NiJpEHIEZDfQyga+lGRf64BqcEowSoIzraJlgRtW7p+4V+/Ncxfw4FxmKs7puc+smv1KvSQI9rlBnwahxJw8msNShkdra/N920bmAJAfU8Hmx4sfGJh7vlh/GoOjMNY1TE+59Fb1paQ4DoTBX0Q5oiKDE4bjPJrCUiCtvr3ay2BSwt/P9hzpQPjGIEzyJfmbbkh6ncCwJUGgL1GRbNNGxDy9x0gggRki0HZpqcYlH9/y2DOlQ6Mg0TEmJ5LA5Gz3yt8IFqR0N6Wwxm0fU4MnxlNdNTRUEdHDUQNSAlKAS+0AQ4AbCwtLf3bns+VDoxjAtCgXjYMxLioGE5cwmfFqOSFQRgbFfU5stVW4ORjAQKcIYLjM2362z210gt5f0cHxrwrNkHXxwKx16jIdI8PQA1E+b05KwajIkdOHRnN34Dgp+BPBLxdgLh9ebn0QNYlc2DMulITeN0de9buJIAP2W/Npm/CUdLeog3HaCJkiM5RCUwgaVFnRbVlKxCaT52hMwj55dudT2wB0f2E+MXl5dljaUvowJi2QhP6/8f2rC4A4A1dQIyLiobOsXhGH4iaAA9HRblFC5Lg85OWEBj55xqEflQ0YESAFuOWCFpA8Dx4eP3y8uzDcUvqwDihYEt6W8wjeh7eG74mK50zzKjIAZVBqAGpgAjQBAXMBiIsLy/PrUT9fg6MBQOjPicy6XzhMKKiSljMebETFcPbs4mUOiqa7Zmjo9ymA1FRgxEAGoDQRIKvLpXnFsJL78BYMDAe2/3qAUC6pt+oGCP9qexZnxXVmVEnKdZWbZIWvlYnLBKMOioyGDkaBqIiADWBsAGITQJqAMCecnnuDvv3cGAsEBgTt+e8Z0VzToyU/YJnxQxR0Y+ICVGxCQgNIGAg8rbdEOT9aaVy6a/MLXBgLBAYj+1Ze9IQ21EZtMkkeiyI8KNiV+JioqUAaOqMOhQV5UNQbdHyvEjEgMMWArVUJMQmAjUFYB0Rm0DUIIJ/LlfmPuLAWCAQ8lu9Y8/qDgLcH7k9p0VFK5O2k5cAneMXQ6ioyP8nt+NQJm3oHOusaKIi/9sCwDYwABmMnLygjIIqKgr9L0CDgOoAWAeAW8rlOZmMuchYEFAe3bP2PHIVTugjawbN18VximEt2teh7TOjxSvqqCifUj9tICqq86KMhAqUCA2OigTyzNjQUbEOQHUEPLlcmfuYA2NBgJgrKuooKIMlnwczRkWTRZuoKLNla3u2Se4MUZF5RQahior8yWdFjo46KiInMwASkODBx5eXSy+6yFgAQB7bs8ZFELIaZ2hnxRjFxWTOBowJUTGQRSNAU0dFjpCNcFTUnGMdiDYA6Vvl8vxRB8YJB2NcBm2SlV7LxGKKZ7skP1t54eQlFBXNedE+K5qoyImMyZw5OvL5sEFEDVRnxToRk+BigxB/WS6XPuvAOOFgjNKfbSD2kkEbjjFQQGtxi1Hbs6F3bOnPyqCToyJnzwxAooZQ1E4dUW/RDFKijXJl/iMOjBMMxiOLq+/zBJ6KeotRBRFpLQWR9YopZWL2Nm1kbZO4BAoiVLLiR0UCqbSoLFqeE5ljpLokvmVk5GyaGJQbhLDRbDY/7cA4wWBMVFvi6JyIhiuTLfdRPCspnoiCCMkpMr/I4NM6NANSyn4+pUPUYBAKjohq664D0oZJYKiN6+DhTQ6MEwpGrUGfyRoVB1k8658TTakYM4fqjXRV5jCxDUCa5FZFEdFRUaovmlvsREUGpABcn5mBWx0YJxSMUSVi/lkxZ1T0I2JS8WwEuZ1UPGuqcnRUVHyiUl+k1OdTOrwdE6psWm7N5qyIdeDkhXADBGwIgH0OjBMIxrjKnLgMOqoXephlYqGzIkdFA8JAVJQRUmbQanuWUiDRBiE1kGBDnhcZjCDqOIOfc2CcQDDmIrmtrEJWco+reNaQ20r6UyS3pG64IEInLLJQgs+K/L2oE+A6R0X+vk1ivwPjBIKxX+kvT1TkMjGfygmViclGq+gysfjiWZlBqzIxmawoTZrPhZ0MmhQAAWBdghJldLzdgXHCwHiMzZmQjkeqLXFnxbiWgnCZWFez1XCKZwNRUVXsBM+KJDaAkM+JG8jbtAfrW5qtww6MkwbGUUh/Ay2eldl0U31KcpsrchqyTIwTFgF1/p6Ao59KYBiAxIBkkHqwTsQRsnXMgXGCwBhHcmtaxTdtkgEy7aw4xOJZXSameMVwmZhVPGvKxJCgQZJX1Fu1gHWOivw9IpxDEhvb3rX1gAPjBIHxy7tP/04bvYci+1uMYVPvbmLB4lnTC91jmViW4lkg2NCFtRwdNcmNdRBiXQNxAwjWOZHZsrXlwDhBWJRvhWmduqjvAICdXL+YKSr2WCY27OLZQJkYkExUiCkdYl5RJi3rTO8A4HqlUrrNRcZJQ6P1fpjiaQPuQOqYOfXVUhAuE+sxKppmq0xlYnI7VmdFPjeas6LHmTTBukDcEIKeW1kpfceBcYLBaN4al5EBejsA6Bpje2zOjSMonk0qE8tWPBuKigxOAXCOoyInMwLg8Wq19KgD45jBKIEGuAAeHfjjv0y2luMEh1reAgFdTQQXBvy4451ntXlTtF3JSIpntQQoZNYskxa5Nassmrdq+n6lsv1lB8axg3HtBKDehqWPNiw1t5x/4Nrr4y2L9y+euWhLQ/p07xAEl0c5z9rN+Kb/2TdwitieuThiUMWzrEUrqY81atlWsK6KaXGDM2d1XoR13qrbBOvN5tzRffu4Z8Z9jG0F7rj5tfe3PfFEWHMmgrMEcKDVpqVrP5FsWXz7zas72gJ3EsEV4VKxkRbPcpkYYJ2LZ7Xy4p8VWQIkgbJu0URF5OIIFOcQ8ZeVSul+XgMHxrFBEeAIu0OAcoewpxAEDT3xoEBcuvZjl3DPdOzHbTeuXgWEC0RwZWbn2QiPxYQyMeMQkVAmFl88awoiiJCjpMyihYBz57Xx/qVb1R+cA+OYwMjnP2zjKXnus2Q+/xwYntFCcB8RLv3ZJy9lq+TYj703rr4PWt6CILrGdp5N9Fhsq+rYYRbPclTkyNnJolmB8d5uNGbv5C3agXFMQOSXPbp7bYkArovYogODgkwtomk7NfNZNprb7kwahbG4cOYiDzd2CsKdbUEXmh4W47FoOEbZ9ddH8SyXickaRb09qwjInCI1JPD0WZFQbCBv1fwzPkO2cb0N8MzKytwj5ja4yDgGQEpiu11/nrSTWFja47dk2xzH+G6fFURLrQzzWW7+1OqONsGCEHC5nT1nKJ6NchMzdI4qoNUNVmnFs0x4MzgZlCqLhvVG44Jv7tv37rMOjGMAoXnJI7tWFwCV0WcSie1HxQQ3CGU/ggebnkidz/KZT5y+ui0jJVyZzXlWeecMongWCNc5KsokRuA58uDFajU4usNFxjGA8ujuNY6K0qokLnExNYld27QuAwskKUZnBriv3YKFT6XMZ/nk/3n5/ULM7GwKuCaz82wPxbNcJqaioKrOkZwib9UE6/UWfHffvtIb9vI7MI4YjEf2rO4AUgZOWaNimpeiTE58X0U196/dhoXP7Eom0XfuXH0fALDc+FEC+FeWx+JAimdZ+lOtqAaUXC7G2TS+WavNfiO89A6MIwZjICqGfHGiFBUrcTGz/NS/Vr+zIbV9QHbcw15oERxoieT5LDt3nrqIaNsHEehvAHA+q8ciys6+bMWzTHbLrVrq0fBALWI0hwPjCMEoZ/oh3htL54QqttNcw4yPYsdtNjiNwLSc8jBKLggChE8vLSWT6Nddd/pPAPCPEeD31FlxMMWzWoM+FxcVHbUzQiDySx3ZZUl/NrcY03hvbOyiQGkPDLLtjn1fRW3qaQYG+XbHBAcJ6eDycumHSb/+zp2v/CcQ+EdE+IfBhvyO82xc8SyXiflnRRBS9jNbtRDw2MpK6Zmo13aRcUSAZOlPeOIJU59o0zmm1TQDndMpelBTTv25LJE8ot6uo8yaCOA+j/DQYnn2cNIS/MVfvLx9Br1rCPAPEGhblMeiqeAmXb0tz4qsQzPRrYtn5b8e/abRmLvLkNzuzDgi8IVfJiD95YiKkWPU/DNjMHGJIrR1d59v7KkjpD+RQAA8D0B7hTj/WKVy8dtxy/Oxj73+L+vrzf8O4H0AkN7NUTFP8SxHSkTx00pl+1Nxr+Ei4wjAaUt/SXRO2F22K3mxaB3jLhs+L4art2Ms7LTlscUjEpwBwH3eluZXFhcveyVpWT760dMfAMA/IILtmKF4FgWcEyg2mk28a9++0jkHxhGALu4lWPoDUDOg0+icLHbHtgF8YDxGqDQsbOxpR0XLe1uOyVCfusMP8aszrdahW2rbTyYt2/UfXv1d4cEHAMS/V73PwN2A66p4lrdpOsfbNZeJIcIzXECb9HwuMg4ZpF3SX8ILine truncated
@@ -0,0 +1 @@
{"v":"5.7.6","fr":25,"ip":0,"op":150,"w":320,"h":200,"nm":"03_Expertise 02","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Line top","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":12,"s":[0]},{"t":13,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[160,26.042,0],"ix":2,"l":2},"a":{"a":0,"k":[150,176.042,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0},"t":12,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[149.984,176.037],[150.031,176.037]],"c":false}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"t":22,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[105,176.074],[195.028,176.085]],"c":false}]},{"t":32,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[149.984,176.037],[150.031,176.037]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.125,0.113999998803,0.113999998803,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":12,"op":32,"st":12,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Picto check","parent":6,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[55,161,0],"ix":2,"l":2},"a":{"a":0,"k":[55,161,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[43.023,137.816],[50.776,145.569],[67.023,129.321]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":20,"op":150,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Right tube stroke","parent":6,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[55,161,0],"ix":2,"l":2},"a":{"a":0,"k":[55,161,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":[[7.72,3.989],[0,0],[0,0],[0,0],[0,-9.289],[-13.255,0],[0,13.255]],"o":[[0,0],[0,0],[0,0],[-7.719,3.989],[0,13.255],[13.255,0],[0,-9.289]],"v":[[11,-3.828],[11,-41.5],[-11,-41.5],[-11,-3.828],[-24,17.5],[0,41.5],[24,17.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.125,0.113999998803,0.113999998803,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[55,119.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":"Glass stroke","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":40,"op":190,"st":40,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Liquid green mask","parent":6,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[55,161,0],"ix":2,"l":2},"a":{"a":0,"k":[55,161,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.72,3.989],[0,0],[0,0],[0,0],[0,-9.289],[-13.255,0],[0,13.255]],"o":[[0,0],[0,0],[0,0],[-7.719,3.989],[0,13.255],[13.255,0],[0,-9.289]],"v":[[66,115.672],[66,78],[44,78],[44,115.672],[31,137],[55,161],[79,137]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.779999976065,0.922000002394,0.976000019148,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 2","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"fl","c":{"a":0,"k":[0.779999976065,0.922000002394,0.976000019148,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":70,"op":220,"st":70,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Liquid green","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[265,161,0],"ix":2,"l":2},"a":{"a":0,"k":[0.49,27.328,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"t":70,"s":[80,0]},{"t":100,"s":[80,74]}],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":70,"s":[0,27],"to":[0,-6.167],"ti":[0,6.167]},{"t":100,"s":[0,-10]}],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.125490196078,0.113725490196,0.113725490196,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector GrLine truncated
@@ -9,9 +9,9 @@
x:Class="Artemis.UI.Screens.Workshop.CurrentUser.CurrentUserView"
x:DataType="currentUser:CurrentUserViewModel">
<Panel Name="Container" IsVisible="{CompiledBinding !Loading}">
<Panel Name="Container">
<!-- Signed out -->
<Ellipse Height="{CompiledBinding Bounds.Height, ElementName=Container}" Width="{CompiledBinding Bounds.Height, ElementName=Container}" IsVisible="{CompiledBinding Name, Converter={x:Static StringConverters.IsNullOrEmpty}}">
<Ellipse Height="{CompiledBinding Bounds.Height, ElementName=Container}" Width="{CompiledBinding Bounds.Height, ElementName=Container}" IsVisible="{CompiledBinding IsAnonymous}">
<Ellipse.ContextFlyout>
<MenuFlyout>
<MenuItem Header="Login" Command="{CompiledBinding Login}">
@@ -27,7 +27,7 @@
</Ellipse>
<!-- Signed in -->
<Ellipse Height="{CompiledBinding Bounds.Height, ElementName=Container}" Width="{CompiledBinding Bounds.Height, ElementName=Container}" IsVisible="{CompiledBinding Name, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" Name="UserMenu">
<Ellipse Height="{CompiledBinding Bounds.Height, ElementName=Container}" Width="{CompiledBinding Bounds.Height, ElementName=Container}" IsVisible="{CompiledBinding !IsAnonymous}" Name="UserMenu">
<Ellipse.ContextFlyout>
<Flyout>
<Grid ColumnDefinitions="Auto,*" RowDefinitions="*,*,*" MinWidth="300">
@@ -39,6 +39,7 @@
<TextBlock Grid.Column="1" Grid.Row="0" Text="{CompiledBinding Name}" Margin="0 4 0 0"></TextBlock>
<TextBlock Grid.Column="1" Grid.Row="1" Text="{CompiledBinding Email}"></TextBlock>
<controls:HyperlinkButton
IsVisible="{CompiledBinding AllowLogout}"
Grid.Column="1"
Grid.Row="2"
Margin="-8 0 0 0"
@@ -54,6 +55,4 @@
</Ellipse.Fill>
</Ellipse>
</Panel>
</UserControl>
@@ -19,8 +19,10 @@ namespace Artemis.UI.Screens.Workshop.CurrentUser;
public class CurrentUserViewModel : ActivatableViewModelBase
{
private readonly IAuthenticationService _authenticationService;
private readonly ObservableAsPropertyHelper<bool> _isAnonymous;
private readonly ILogger _logger;
private readonly IWindowService _windowService;
private bool _allowLogout = true;
private Bitmap? _avatar;
private string? _email;
private bool _loading = true;
@@ -34,6 +36,8 @@ public class CurrentUserViewModel : ActivatableViewModelBase
_windowService = windowService;
Login = ReactiveCommand.CreateFromTask(ExecuteLogin);
_isAnonymous = this.WhenAnyValue(vm => vm.Loading, vm => vm.Name, (l, n) => l || n == null).ToProperty(this, vm => vm.IsAnonymous);
this.WhenActivated(d =>
{
Task.Run(AutoLogin);
@@ -41,41 +45,50 @@ public class CurrentUserViewModel : ActivatableViewModelBase
});
}
public bool IsAnonymous => _isAnonymous.Value;
public bool AllowLogout
{
get => _allowLogout;
set => RaiseAndSetIfChanged(ref _allowLogout, value);
}
public bool Loading
{
get => _loading;
set => RaiseAndSetIfChanged(ref _loading, value);
private set => RaiseAndSetIfChanged(ref _loading, value);
}
public string? UserId
{
get => _userId;
set => RaiseAndSetIfChanged(ref _userId, value);
private set => RaiseAndSetIfChanged(ref _userId, value);
}
public string? Name
{
get => _name;
set => RaiseAndSetIfChanged(ref _name, value);
private set => RaiseAndSetIfChanged(ref _name, value);
}
public string? Email
{
get => _email;
set => RaiseAndSetIfChanged(ref _email, value);
private set => RaiseAndSetIfChanged(ref _email, value);
}
public Bitmap? Avatar
{
get => _avatar;
set => RaiseAndSetIfChanged(ref _avatar, value);
private set => RaiseAndSetIfChanged(ref _avatar, value);
}
public ReactiveCommand<Unit, Unit> Login { get; }
public void Logout()
{
_authenticationService.Logout();
if (AllowLogout)
_authenticationService.Logout();
}
private async Task ExecuteLogin(CancellationToken cancellationToken)
@@ -8,13 +8,10 @@
x:DataType="currentUser:WorkshopLoginViewModel">
<StackPanel Width="400">
<TextBlock TextWrapping="Wrap">
In order to login you must enter your Artemis credentials in a browser.
</TextBlock>
<TextBlock TextWrapping="Wrap" Margin="0 15">
If you do not have an account yet you can create one in the browser too. Alternatively you can log in with Google or Discord.
A browser window has opened where you'll be able to create an account and/or log in.
</TextBlock>
<TextBlock>Waiting for login...</TextBlock>
<TextBlock Margin="0 15 0 0">Waiting for log in...</TextBlock>
<ProgressBar Margin="0 5 0 0" IsIndeterminate="True"></ProgressBar>
</StackPanel>
</UserControl>
@@ -0,0 +1,48 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:steps="clr-namespace:Artemis.UI.Screens.Workshop.SubmissionWizard.Steps"
xmlns:workshop="clr-namespace:Artemis.WebClient.Workshop;assembly=Artemis.WebClient.Workshop"
xmlns:converters="clr-namespace:Artemis.UI.Shared.Converters;assembly=Artemis.UI.Shared"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Workshop.SubmissionWizard.Steps.EntryTypeView"
x:DataType="steps:EntryTypeViewModel">
<UserControl.Resources>
<converters:EnumToBooleanConverter x:Key="EnumBoolConverter" />
</UserControl.Resources>
<StackPanel>
<StackPanel.Styles>
<Styles>
<Style Selector="TextBlock">
<Setter Property="TextWrapping" Value="Wrap"></Setter>
</Style>
</Styles>
</StackPanel.Styles>
<TextBlock Theme="{StaticResource TitleTextBlockStyle}" TextWrapping="Wrap">
Submission type
</TextBlock>
<TextBlock TextWrapping="Wrap">
Please select the type of content you want to submit to the workshop.
</TextBlock>
<RadioButton GroupName="EntryType"
Margin="0 15 0 0"
IsChecked="{CompiledBinding SelectedEntryType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static workshop:EntryType.Profile}}" >
<RadioButton.Content>
<StackPanel>
<TextBlock>Profile</TextBlock>
<TextBlock Classes="subtitle" TextWrapping="Wrap">A profile which others can install to enjoy new lighting and interactions.</TextBlock>
</StackPanel>
</RadioButton.Content>
</RadioButton>
<RadioButton GroupName="EntryType"
IsChecked="{CompiledBinding SelectedEntryType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static workshop:EntryType.Layout}}">
<RadioButton.Content>
<StackPanel>
<TextBlock>Layout</TextBlock>
<TextBlock Classes="subtitle" TextWrapping="Wrap">A layout providing users with a visual representation of a device.</TextBlock>
</StackPanel>
</RadioButton.Content>
</RadioButton>
</StackPanel>
</UserControl>
@@ -0,0 +1,17 @@
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps;
public partial class EntryTypeView : ReactiveUserControl<EntryTypeViewModel>
{
public EntryTypeView()
{
InitializeComponent();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
@@ -0,0 +1,41 @@
using System;
using System.Reactive;
using System.Reactive.Linq;
using Artemis.WebClient.Workshop;
using ReactiveUI;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps;
public class EntryTypeViewModel : SubmissionViewModel
{
private EntryType? _selectedEntryType;
/// <inheritdoc />
public EntryTypeViewModel()
{
GoBack = ReactiveCommand.Create(() => State.ChangeScreen<WelcomeStepViewModel>());
Continue = ReactiveCommand.Create(ExecuteContinue, this.WhenAnyValue(vm => vm.SelectedEntryType).Select(e => e != null));
}
public EntryType? SelectedEntryType
{
get => _selectedEntryType;
set => RaiseAndSetIfChanged(ref _selectedEntryType, value);
}
/// <inheritdoc />
public override ReactiveCommand<Unit, Unit> Continue { get; }
/// <inheritdoc />
public override ReactiveCommand<Unit, Unit> GoBack { get; }
private void ExecuteContinue()
{
if (SelectedEntryType == null)
return;
State.EntryType = SelectedEntryType.Value;
if (State.EntryType == EntryType.Profile)
State.ChangeScreen<ProfileSelectionStepViewModel>();
}
}
@@ -0,0 +1,33 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:steps="clr-namespace:Artemis.UI.Screens.Workshop.SubmissionWizard.Steps"
mc:Ignorable="d" d:DesignWidth="970" d:DesignHeight="625"
x:Class="Artemis.UI.Screens.Workshop.SubmissionWizard.Steps.LoginStepView"
x:DataType="steps:LoginStepViewModel">
<StackPanel>
<StackPanel.Styles>
<Styles>
<Style Selector="TextBlock">
<Setter Property="TextAlignment" Value="Center"></Setter>
<Setter Property="TextWrapping" Value="Wrap"></Setter>
</Style>
</Styles>
</StackPanel.Styles>
<TextBlock Theme="{StaticResource TitleTextBlockStyle}">First things first</TextBlock>
<TextBlock>
<Run>In order to submit anything to the workshop you must be logged in.</Run>
<LineBreak />
<Run>Creating an account is free and we'll not bother you with a newsletter or crap like that.</Run>
</TextBlock>
<Lottie Path="/Assets/Animations/login-pending.json" RepeatCount="-1" Width="250" Height="250"></Lottie>
<TextBlock>
<Run>Click continue to (create an account) and log in.</Run>
<LineBreak/>
<Run>You'll also be able to log in with Google or Discord.</Run>
</TextBlock>
</StackPanel>
</UserControl>
@@ -0,0 +1,17 @@
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps;
public partial class LoginStepView : ReactiveUserControl<LoginStepView>
{
public LoginStepView()
{
InitializeComponent();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
@@ -0,0 +1,50 @@
using System;
using System.Linq;
using System.Reactive;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using Artemis.UI.Screens.Workshop.CurrentUser;
using Artemis.UI.Shared.Services;
using Artemis.WebClient.Workshop.Services;
using FluentAvalonia.UI.Controls;
using IdentityModel;
using ReactiveUI;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps;
public class LoginStepViewModel : SubmissionViewModel
{
private readonly IAuthenticationService _authenticationService;
private readonly IWindowService _windowService;
public LoginStepViewModel(IAuthenticationService authenticationService, IWindowService windowService)
{
_authenticationService = authenticationService;
_windowService = windowService;
Continue = ReactiveCommand.CreateFromTask(ExecuteLogin);
ShowGoBack = false;
ShowHeader = false;
ContinueText = "Log In";
}
/// <inheritdoc />
public override ReactiveCommand<Unit, Unit> Continue { get; }
/// <inheritdoc />
public override ReactiveCommand<Unit, Unit> GoBack { get; } = null!;
private async Task ExecuteLogin(CancellationToken ct)
{
ContentDialogResult result = await _windowService.CreateContentDialog().WithViewModel(out WorkshopLoginViewModel _).WithTitle("Workshop login").ShowAsync();
if (result != ContentDialogResult.Primary)
return;
Claim? emailVerified = _authenticationService.Claims.FirstOrDefault(c => c.Type == JwtClaimTypes.EmailVerified);
if (emailVerified?.Value == "true")
State.ChangeScreen<EntryTypeViewModel>();
else
State.ChangeScreen<ValidateEmailStepViewModel>();
}
}
@@ -0,0 +1,10 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:steps="clr-namespace:Artemis.UI.Screens.Workshop.SubmissionWizard.Steps"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Workshop.SubmissionWizard.Steps.ProfileSelectionStepView"
x:DataType="steps:ProfileSelectionStepViewModel">
Welcome to Avalonia!
</UserControl>
@@ -0,0 +1,18 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps;
public partial class ProfileSelectionStepView : UserControl
{
public ProfileSelectionStepView()
{
InitializeComponent();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
@@ -0,0 +1,13 @@
using System.Reactive;
using ReactiveUI;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps;
public class ProfileSelectionStepViewModel : SubmissionViewModel
{
/// <inheritdoc />
public override ReactiveCommand<Unit, Unit> Continue { get; }
/// <inheritdoc />
public override ReactiveCommand<Unit, Unit> GoBack { get; }
}
@@ -0,0 +1,41 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:steps="clr-namespace:Artemis.UI.Screens.Workshop.SubmissionWizard.Steps"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
mc:Ignorable="d" d:DesignWidth="970" d:DesignHeight="625"
x:Class="Artemis.UI.Screens.Workshop.SubmissionWizard.Steps.ValidateEmailStepView"
x:DataType="steps:ValidateEmailStepViewModel">
<StackPanel >
<StackPanel.Styles>
<Styles>
<Style Selector="TextBlock">
<Setter Property="TextAlignment" Value="Center"></Setter>
</Style>
</Styles>
</StackPanel.Styles>
<TextBlock Theme="{StaticResource TitleTextBlockStyle}" TextWrapping="Wrap">Confirm email address</TextBlock>
<TextBlock TextWrapping="Wrap">
<Run>Before you can continue, please confirm your email address.</Run> (<Run Text="{CompiledBinding Email.Value}"></Run>)
<LineBreak />
<Run>You'll find the confirmation mail in your inbox.</Run>
<LineBreak />
<LineBreak />
<TextBlock>Don't see an email? Check your spam box!</TextBlock>
</TextBlock>
<Lottie Path="/Assets/Animations/email.json" RepeatCount="-1" Width="200" Height="200"></Lottie>
<Button Margin="0 0 0 15" HorizontalAlignment="Center" Command="{CompiledBinding Refresh}">
<StackPanel Orientation="Horizontal" Spacing="5">
<avalonia:MaterialIcon Kind="Refresh" />
<TextBlock>Refresh</TextBlock>
</StackPanel>
</Button>
<TextBlock Theme="{StaticResource CaptionTextBlockStyle}">
PS: We take this step to avoid the workshop getting spammed with low quality content.
</TextBlock>
</StackPanel>
</UserControl>
@@ -0,0 +1,17 @@
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps;
public partial class ValidateEmailStepView : ReactiveUserControl<ValidateEmailStepViewModel>
{
public ValidateEmailStepView()
{
InitializeComponent();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
@@ -0,0 +1,78 @@
using System;
using System.Linq;
using System.Reactive;
using System.Reactive.Disposables;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using Artemis.WebClient.Workshop.Services;
using IdentityModel;
using ReactiveUI;
using Timer = System.Timers.Timer;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps;
public class ValidateEmailStepViewModel : SubmissionViewModel
{
private readonly IAuthenticationService _authenticationService;
private ObservableAsPropertyHelper<Claim?>? _email;
public ValidateEmailStepViewModel(IAuthenticationService authenticationService)
{
_authenticationService = authenticationService;
Continue = ReactiveCommand.Create(ExecuteContinue);
Refresh = ReactiveCommand.CreateFromTask(ExecuteRefresh);
ShowGoBack = false;
ShowHeader = false;
this.WhenActivated(d =>
{
_email = authenticationService.GetClaim(JwtClaimTypes.Email).ToProperty(this, vm => vm.Email).DisposeWith(d);
Timer updateTimer = new(TimeSpan.FromSeconds(15));
updateTimer.Elapsed += (_, _) => Task.Run(Update);
updateTimer.Start();
updateTimer.DisposeWith(d);
});
}
/// <inheritdoc />
public override ReactiveCommand<Unit, Unit> Continue { get; }
/// <inheritdoc />
public override ReactiveCommand<Unit, Unit> GoBack { get; } = null!;
public ReactiveCommand<Unit, Unit> Refresh { get; }
public Claim? Email => _email?.Value;
private async Task Update()
{
try
{
// Use the refresh token to login again, updating claims
await _authenticationService.AutoLogin(true);
Claim? emailVerified = _authenticationService.Claims.FirstOrDefault(c => c.Type == JwtClaimTypes.EmailVerified);
if (emailVerified?.Value == "true")
ExecuteContinue();
}
catch (Exception)
{
// ignored, meh
}
}
private void ExecuteContinue()
{
State.ChangeScreen<EntryTypeViewModel>();
}
private async Task ExecuteRefresh(CancellationToken ct)
{
await Update();
await Task.Delay(1000, ct);
}
}
@@ -3,50 +3,17 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:steps="clr-namespace:Artemis.UI.Screens.Workshop.SubmissionWizard.Steps"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
mc:Ignorable="d" d:DesignWidth="970" d:DesignHeight="625"
x:Class="Artemis.UI.Screens.Workshop.SubmissionWizard.Steps.WelcomeStepView"
x:DataType="steps:WelcomeStepViewModel">
<StackPanel>
<TextBlock Theme="{StaticResource TitleTextBlockStyle}">Welcome to the Workshop Submission Wizard 🧙</TextBlock>
<TextBlock>Here we'll take you, step by step, through the process of uploading your submission to the workshop.</TextBlock>
<StackPanel Margin="0 50 0 0" >
<TextBlock Theme="{StaticResource TitleTextBlockStyle}" TextAlignment="Center" TextWrapping="Wrap">
Welcome to the Workshop Submission Wizard 🧙
</TextBlock>
<TextBlock TextAlignment="Center" TextWrapping="Wrap">
Here we'll take you, step by step, through the process of uploading your submission to the workshop.
</TextBlock>
<StackPanel IsVisible="{CompiledBinding !IsLoggedIn}" Margin="0 35 0 0">
<TextBlock Theme="{StaticResource SubtitleTextBlockStyle}" TextWrapping="Wrap">First things first</TextBlock>
<TextBlock TextWrapping="Wrap">
<Run>In order to submit anything to the workshop you must be logged in.</Run>
<LineBreak />
<LineBreak />
<Run>Creating an account is free and we'll not bother you with a newsletter or crap like that. You can also log in with Google or Discord.</Run>
</TextBlock>
<Button Margin="0 15 0 0" Command="{CompiledBinding Login}">
<StackPanel Orientation="Horizontal" Spacing="5">
<avalonia:MaterialIcon Kind="ExternalLink" />
<TextBlock>Create account or log in</TextBlock>
</StackPanel>
</Button>
</StackPanel>
<StackPanel IsVisible="{CompiledBinding ShowMissingVerification}" Margin="0 35 0 0">
<TextBlock Theme="{StaticResource SubtitleTextBlockStyle}" TextWrapping="Wrap">Confirm email address</TextBlock>
<TextBlock TextWrapping="Wrap">
<Run>Before you can continue, please confirm your email address.</Run> (<Run Text="{CompiledBinding Email.Value}"></Run>)
<LineBreak />
<Run>You'll find the confirmation mail in your inbox.</Run>
<LineBreak />
<LineBreak />
<TextBlock>Don't see an email? Check your spam box!</TextBlock>
</TextBlock>
<Button Margin="0 15 0 5" Command="{CompiledBinding Refresh}">
<StackPanel Orientation="Horizontal" Spacing="5">
<avalonia:MaterialIcon Kind="Refresh" />
<TextBlock>Refresh</TextBlock>
</StackPanel>
</Button>
<TextBlock Theme="{StaticResource CaptionTextBlockStyle}">PS: We take this step to avoid the workshop getting flooded with bogus content.</TextBlock>
</StackPanel>
<Lottie Path="/Assets/Animations/workshop-wizard.json" RepeatCount="1" Width="300" Height="400"></Lottie>
</StackPanel>
</UserControl>
@@ -1,50 +1,24 @@
using System;
using System.Linq;
using System.Reactive;
using System.Reactive.Disposables;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using Artemis.UI.Screens.Workshop.CurrentUser;
using Artemis.UI.Shared.Services;
using Artemis.WebClient.Workshop.Services;
using IdentityModel;
using ReactiveUI;
using Timer = System.Timers.Timer;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps;
public class WelcomeStepViewModel : SubmissionViewModel
{
private readonly IAuthenticationService _authenticationService;
private readonly ObservableAsPropertyHelper<bool> _showMissingVerification;
private readonly IWindowService _windowService;
private ObservableAsPropertyHelper<Claim?>? _email;
private ObservableAsPropertyHelper<Claim?>? _emailVerified;
private ObservableAsPropertyHelper<bool>? _isLoggedIn;
public WelcomeStepViewModel(IAuthenticationService authenticationService, IWindowService windowService)
public WelcomeStepViewModel(IAuthenticationService authenticationService)
{
_authenticationService = authenticationService;
_windowService = windowService;
_showMissingVerification = this.WhenAnyValue(vm => vm.IsLoggedIn, vm => vm.EmailVerified, (l, v) => l && (v == null || v.Value == "false")).ToProperty(this, vm => vm.ShowMissingVerification);
Continue = ReactiveCommand.CreateFromTask(ExecuteContinue);
ShowHeader = false;
ShowGoBack = false;
Continue = ReactiveCommand.Create(ExecuteContinue);
Login = ReactiveCommand.CreateFromTask(ExecuteLogin);
Refresh = ReactiveCommand.CreateFromTask(ExecuteRefresh);
this.WhenActivated(d =>
{
_isLoggedIn = authenticationService.IsLoggedIn.ToProperty(this, vm => vm.IsLoggedIn).DisposeWith(d);
_emailVerified = authenticationService.GetClaim(JwtClaimTypes.EmailVerified).ToProperty(this, vm => vm.EmailVerified).DisposeWith(d);
_email = authenticationService.GetClaim(JwtClaimTypes.Email).ToProperty(this, vm => vm.Email).DisposeWith(d);
Timer updateTimer = new(TimeSpan.FromSeconds(15));
updateTimer.Elapsed += (_, _) => Task.Run(Update);
updateTimer.Start();
updateTimer.DisposeWith(d);
});
}
/// <inheritdoc />
@@ -53,43 +27,20 @@ public class WelcomeStepViewModel : SubmissionViewModel
/// <inheritdoc />
public override ReactiveCommand<Unit, Unit> GoBack { get; } = null!;
public ReactiveCommand<Unit, Unit> Login { get; }
public ReactiveCommand<Unit, Unit> Refresh { get; }
public bool ShowMissingVerification => _showMissingVerification.Value;
public bool IsLoggedIn => _isLoggedIn?.Value ?? false;
public Claim? EmailVerified => _emailVerified?.Value;
public Claim? Email => _email?.Value;
private async Task Update()
private async Task ExecuteContinue()
{
if (EmailVerified?.Value == "true")
return;
bool loggedIn = await _authenticationService.AutoLogin(true);
try
if (!loggedIn)
{
// Use the refresh token to login again, updating claims
await _authenticationService.AutoLogin(true);
State.ChangeScreen<LoginStepViewModel>();
}
catch (Exception)
else
{
// ignored, meh
if (_authenticationService.Claims.Any(c => c.Type == JwtClaimTypes.EmailVerified && c.Value == "true"))
State.ChangeScreen<EntryTypeViewModel>();
else
State.ChangeScreen<ValidateEmailStepViewModel>();
}
}
private void ExecuteContinue()
{
throw new NotImplementedException();
}
private async Task ExecuteLogin(CancellationToken ct)
{
await _windowService.CreateContentDialog().WithViewModel(out WorkshopLoginViewModel _).WithTitle("Workshop login").ShowAsync();
}
private async Task ExecuteRefresh(CancellationToken ct)
{
await Update();
await Task.Delay(1000, ct);
}
}
@@ -0,0 +1,43 @@
using System.Reactive;
using Artemis.UI.Shared;
using ReactiveUI;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard;
public abstract class SubmissionViewModel : ActivatableViewModelBase
{
private string _continueText = "Continue";
private bool _showFinish;
private bool _showGoBack = true;
private bool _showHeader = true;
public SubmissionWizardViewModel WizardViewModel { get; set; } = null!;
public SubmissionWizardState State { get; set; } = null!;
public abstract ReactiveCommand<Unit, Unit> Continue { get; }
public abstract ReactiveCommand<Unit, Unit> GoBack { get; }
public bool ShowHeader
{
get => _showHeader;
set => RaiseAndSetIfChanged(ref _showHeader, value);
}
public bool ShowGoBack
{
get => _showGoBack;
set => RaiseAndSetIfChanged(ref _showGoBack, value);
}
public bool ShowFinish
{
get => _showFinish;
set => RaiseAndSetIfChanged(ref _showFinish, value);
}
public string ContinueText
{
get => _continueText;
set => RaiseAndSetIfChanged(ref _continueText, value);
}
}
@@ -0,0 +1,34 @@
using System.Collections.Generic;
using System.IO;
using Artemis.WebClient.Workshop;
using DryIoc;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard;
public class SubmissionWizardState
{
private readonly SubmissionWizardViewModel _wizardViewModel;
private readonly IContainer _container;
public SubmissionWizardState(SubmissionWizardViewModel wizardViewModel, IContainer container)
{
_wizardViewModel = wizardViewModel;
_container = container;
}
public EntryType EntryType { get; set; }
public string Name { get; set; } = string.Empty;
public Stream? Icon { get; set; }
public string Summary { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public List<int> Categories { get; set; } = new();
public List<int> Tags { get; set; } = new();
public List<Stream> Images { get; set; } = new();
public void ChangeScreen<TSubmissionViewModel>() where TSubmissionViewModel : SubmissionViewModel
{
_wizardViewModel.Screen = _container.Resolve<TSubmissionViewModel>();
}
}
@@ -17,7 +17,8 @@
<Grid Margin="15" RowDefinitions="Auto,*,Auto">
<Grid RowDefinitions="*,*" ColumnDefinitions="Auto,*,Auto" Margin="0 0 0 15">
<ContentControl Grid.Column="0" Grid.RowSpan="2" Width="65" Height="65" VerticalAlignment="Center" Margin="0 0 20 0" Content="{CompiledBinding CurrentUserViewModel}"/>
<TextBlock Grid.Row="0" Grid.Column="1" FontSize="36" VerticalAlignment="Bottom" Text="{CompiledBinding CurrentUserViewModel.Name, FallbackValue=Not logged in}"/>
<TextBlock Grid.Row="0" Grid.Column="1" FontSize="36" VerticalAlignment="Bottom" Text="{CompiledBinding CurrentUserViewModel.Name}" IsVisible="{CompiledBinding !CurrentUserViewModel.IsAnonymous}"/>
<TextBlock Grid.Row="0" Grid.Column="1" FontSize="36" VerticalAlignment="Bottom" Text="Anon 🕵️" IsVisible="{CompiledBinding CurrentUserViewModel.IsAnonymous}"/>
<StackPanel Grid.Row="0" Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Bottom" Orientation="Horizontal">
<controls:HyperlinkButton Classes="icon-button" ToolTip.Tip="View Wiki" NavigateUri="https://wiki.artemis-rgb.com?mtm_campaign=artemis&amp;mtm_kwd=workshop-wizard">
@@ -44,9 +45,7 @@
<Button Command="{CompiledBinding Screen.GoBack}" IsVisible="{CompiledBinding Screen.ShowGoBack}">
Back
</Button>
<Button Command="{CompiledBinding Screen.Continue}" IsVisible="{CompiledBinding !Screen.ShowFinish}" Width="80">
Continue
</Button>
<Button Command="{CompiledBinding Screen.Continue}" IsVisible="{CompiledBinding !Screen.ShowFinish}" Width="80" Content="{CompiledBinding Screen.ContinueText}"/>
<Button Command="{CompiledBinding Screen.Continue}" IsVisible="{CompiledBinding Screen.ShowFinish}" Width="80">
Finish
</Button>
@@ -1,19 +1,24 @@
using System.Reactive;
using Artemis.UI.Screens.Workshop.CurrentUser;
using Artemis.UI.Screens.Workshop.CurrentUser;
using Artemis.UI.Screens.Workshop.SubmissionWizard.Steps;
using Artemis.UI.Shared;
using ReactiveUI;
using DryIoc;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard;
public class SubmissionWizardViewModel : DialogViewModelBase<bool>
{
private readonly SubmissionWizardState _state;
private SubmissionViewModel _screen;
public SubmissionWizardViewModel(CurrentUserViewModel currentUserViewModel, WelcomeStepViewModel welcomeStepViewModel)
public SubmissionWizardViewModel(IContainer container, CurrentUserViewModel currentUserViewModel, WelcomeStepViewModel welcomeStepViewModel)
{
_state = new SubmissionWizardState(this, container);
_screen = welcomeStepViewModel;
_screen.WizardViewModel = this;
_screen.State = _state;
CurrentUserViewModel = currentUserViewModel;
CurrentUserViewModel.AllowLogout = false;
}
public CurrentUserViewModel CurrentUserViewModel { get; }
@@ -21,27 +26,11 @@ public class SubmissionWizardViewModel : DialogViewModelBase<bool>
public SubmissionViewModel Screen
{
get => _screen;
set => RaiseAndSetIfChanged(ref _screen, value);
}
}
public abstract class SubmissionViewModel : ActivatableViewModelBase
{
private bool _showFinish;
private bool _showGoBack = true;
public abstract ReactiveCommand<Unit, Unit> Continue { get; }
public abstract ReactiveCommand<Unit, Unit> GoBack { get; }
public bool ShowGoBack
{
get => _showGoBack;
set => RaiseAndSetIfChanged(ref _showGoBack, value);
}
public bool ShowFinish
{
get => _showFinish;
set => RaiseAndSetIfChanged(ref _showFinish, value);
set
{
value.WizardViewModel = this;
value.State = _state;
RaiseAndSetIfChanged(ref _screen, value);
}
}
}
@@ -79,14 +79,14 @@ internal class AuthenticationService : CorePropertyChanged, IAuthenticationServi
if (response.IsError)
{
if (response.Error == OidcConstants.TokenErrors.ExpiredToken)
if (response.Error is OidcConstants.TokenErrors.ExpiredToken or OidcConstants.TokenErrors.InvalidGrant)
return false;
throw new ArtemisWebClientException("Failed to request refresh token: " + response.Error);
}
SetCurrentUser(response);
return false;
return true;
}
private static byte[] HashSha256(string inputString)
@@ -2,6 +2,6 @@ namespace Artemis.WebClient.Workshop;
public static class WorkshopConstants
{
public const string AUTHORITY_URL = "https://identity.artemis-rgb.com";
public const string AUTHORITY_URL = "https://localhost:5001";
public const string WORKSHOP_URL = "https://workshop.artemis-rgb.com";
}