Merge branch 'vnext' of github.com:pazof/yavsc into vnext

This commit is contained in:
2017-03-10 11:20:31 +01:00
25 changed files with 266 additions and 146 deletions

View File

@ -73,20 +73,29 @@
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Compile Include="IAccountBalance.cs" />
<Compile Include="IActivity.cs" />
<Compile Include="IApplicationUser.cs" />
<Compile Include="Billing\IAccountBalance.cs" />
<Compile Include="Billing\IcommandLine.cs" />
<Compile Include="Billing\IEstimate.cs" />
<Compile Include="Blogspot\IBlog.cs" />
<Compile Include="IBaseTrackedEntity.cs" />
<Compile Include="IBlog.cs" />
<Compile Include="ICircle.cs" />
<Compile Include="ICircleMember.cs" />
<Compile Include="ICommandForm.cs" />
<Compile Include="IContact.cs" />
<Compile Include="ICoWorking.cs" />
<Compile Include="IGoogleCloudMobileDeclaration.cs" />
<Compile Include="ILocation.cs" />
<Compile Include="IPosition.cs" />
<Compile Include="Identity\IApplicationUser.cs" />
<Compile Include="Identity\IChatUserInfo.cs" />
<Compile Include="Identity\ICircle.cs" />
<Compile Include="Identity\ICircleMember.cs" />
<Compile Include="Identity\Security\ICircleAuthorization.cs" />
<Compile Include="Identity\Security\ICircleAuthorized.cs" />
<Compile Include="IT\ICode.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Workflow\IActivity.cs" />
<Compile Include="Workflow\IBlackListed.cs" />
<Compile Include="Workflow\ICommandForm.cs" />
<Compile Include="Workflow\IContact.cs" />
<Compile Include="Workflow\ICoWorking.cs" />
<Compile Include="Workflow\IGoogleCloudMobileDeclaration.cs" />
<Compile Include="Workflow\ILocation.cs" />
<Compile Include="Workflow\IPerformerProfile.cs" />
<Compile Include="Workflow\IPosition.cs" />
<Compile Include="Workflow\ISpecializationSettings.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
@ -97,8 +106,6 @@
</ItemGroup>
<ItemGroup>
<Content Include="project.json" />
<Compile Include="IChatUserInfo.cs" />
<Compile Include="IBlackListed.cs" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">

View File

@ -3,22 +3,20 @@
"version": 2,
"targets": {
".NETFramework,Version=v4.5.1": {},
".NETPortable,Version=v4.5,Profile=Profile111": {},
".NETFramework,Version=v4.5.1/debian.8-x86": {},
".NETFramework,Version=v4.5.1/debian.8-x64": {},
".NETPortable,Version=v4.5,Profile=Profile111/debian.8-x86": {},
".NETPortable,Version=v4.5,Profile=Profile111/debian.8-x64": {}
".NETPortable,Version=v4.5,Profile=Profile111": {}
},
"libraries": {},
"projectFileDependencyGroups": {
"": [],
".NETFramework,Version=v4.5.1": [],
".NETPortable,Version=v4.5,Profile=Profile111": [
"fx/System.Runtime >= 4.0.0",
"fx/System.Globalization >= 4.0.0",
"fx/System.Resources.ResourceManager >= 4.0.0",
"fx/System.Collections >= 4.0.0",
"fx/System.Collections.Generic >= 4.0.0"
"System.Collections >= 4.0.0",
"System.Collections.Generic >= 4.0.0",
"System.Globalization >= 4.0.0",
"System.Resources.ResourceManager >= 4.0.0",
"System.Runtime >= 4.0.0"
]
}
},
"tools": {},
"projectFileToolGroups": {}
}

View File

@ -6,6 +6,7 @@ using System.Net;
using System.Runtime.Serialization.Json;
using System.Text;
using ZicMoove.Model.Auth.Account;
using System.IO;
namespace ZicMoove.Droid
{
@ -13,13 +14,23 @@ namespace ZicMoove.Droid
public static class YavscHelpers
{
public static void SetRegId(this User user, string regId)
public static string GetSpecialFolder(this string specialPath)
{
if (user.YavscTokens == null)
if (specialPath == null)
throw new InvalidOperationException();
var appData =
System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData);
string imagesFolder = System.IO.Path.Combine(appData, specialPath);
DirectoryInfo di = new DirectoryInfo(imagesFolder);
// FIXME Create this folder at app startup
if (!di.Exists) di.Create();
return imagesFolder;
}
public static string GetTmpDir ()
{
return GetSpecialFolder("tmp");
}
}
}

View File

@ -505,11 +505,7 @@ namespace ZicMoove.Droid
get
{
if (imagesFolder != null) return imagesFolder;
var appData =
System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData);
imagesFolder = System.IO.Path.Combine(appData, Constants.ImagePath);
DirectoryInfo di = new DirectoryInfo(imagesFolder);
if (!di.Exists) di.Create();
imagesFolder = Constants.ImagePath.GetSpecialFolder();
return imagesFolder;
}
}
@ -541,11 +537,11 @@ namespace ZicMoove.Droid
}
}
}
var acode = photo[1];
var act = DataManager.Instance.Activities.LocalGet(acode);
act.LocalPhoto = Path.Combine(images, $"{acode}.svg");
}
}
foreach (var act in DataManager.Instance.Activities)
{ act.LocalPhoto = Path.Combine(images, $"{act.Code}.svg"); }
DataManager.Instance.Activities.SaveEntity();
}
}

View File

@ -37,7 +37,8 @@ namespace ZicMoove.Droid.Services.GCMHandlers
var client = JsonConvert.DeserializeObject<ClientProviderInfo>(clientJson);
var estimate = new Estimate
{
Id = eid
Id = eid,
CommandType = data.GetString("CommandType")
};
var dateString = data.GetString("ProviderValidationDate");
DateTime evDate;

View File

@ -195,27 +195,32 @@ namespace ZicMoove
}
BookQueriesPage bQueriesPage;
AccountChooserPage accChooserPage;
ActivityPage homePage;
static BookQueriesPage bQueriesPage;
static AccountChooserPage accChooserPage;
static ActivityPage homePage;
private static UserProfilePage userProfilePage;
public static UserProfilePage UserProfilePage
{ get { return userProfilePage; } }
ChatPage chatPage;
PinPage pinPage;
static ChatPage chatPage;
static PinPage pinPage;
public static void ShowPage(Page page)
public static async void ShowPage(Page page)
{
if (page == homePage)
{
await Navigation.PopToRootAsync();
return;
}
if (Navigation.NavigationStack.Contains(page))
{
if (Navigation.NavigationStack.Last() == page) return;
Navigation.RemovePage(page);
page.Parent = null;
}
Navigation.PushAsync(page);
await Navigation.PushAsync(page);
}
private void BuildMainPage()
@ -263,7 +268,7 @@ namespace ZicMoove
BindingContext = new ChatViewModel()
};
pinPage = new PinPage();
pinPage = new PinPage { Title = Strings.Carte };
// var mainPage = new NavigationPage(bQueriesPage);
@ -322,6 +327,7 @@ namespace ZicMoove
masterDetail.ToolbarItems.Add(tiHome);
masterDetail.ToolbarItems.Add(tiSetts);
masterDetail.ToolbarItems.Add(tiPubChat);
masterDetail.ToolbarItems.Add(tiPinPage);
this.MainPage = masterDetail;
NavigationService = new NavigationService(Navigation);

View File

@ -142,9 +142,10 @@ namespace ZicMoove.Data
created = response.IsSuccessStatusCode;
if (!created)
{
// TODO throw custom exception, and catch to inform user
var errcontent = await response.Content.ReadAsStringAsync();
Debug.WriteLine(string.Format(Strings.CreationFailed));
Debug.WriteLine(string.Format(Strings.CreationFailed,stringContent,ControllerUri.AbsoluteUri));
Debug.WriteLine(errcontent);
}
else

View File

@ -1,12 +0,0 @@
using System;
namespace ZicMoove.Interfaces
{
public interface IBillingLine
{
int Count { get; set; }
string Description { get; set; }
TimeSpan Duration { get; set; }
decimal UnitaryCost { get; set; }
}
}

View File

@ -1,19 +0,0 @@
using ZicMoove.Model.Workflow;
using System.Collections.Generic;
namespace ZicMoove.Model.Interfaces
{
public interface IEstimate
{
List<string> AttachedFiles { get; set; }
List<string> AttachedGraphics { get; }
List<BillingLine> Bill { get; set; }
string ClientId { get; set; }
long? CommandId { get; set; }
string CommandType { get; set; }
string Description { get; set; }
long Id { get; set; }
string OwnerId { get; set; }
string Title { get; set; }
}
}

View File

@ -1,10 +1,11 @@
using Newtonsoft.Json;
using System;
using YavscLib;
using XLabs.Forms.Mvvm;
namespace ZicMoove.Model.Workflow
{
public class Activity : IActivity
using YavscLib;
public class Activity : ViewModel, IActivity
{
public string Code
{
@ -74,6 +75,11 @@ namespace ZicMoove.Model.Workflow
get;
set;
}
public string LocalPhoto { get; set; }
private string photo;
public string LocalPhoto {
get { return photo; }
set { SetProperty<string>(ref photo, value);
} }
}
}

View File

@ -9,7 +9,7 @@ namespace ZicMoove.Model.Workflow
{
public class CommandForm : ICommandForm
{
public string Action
public string ActionName
{
get; set;
}

View File

@ -7,9 +7,9 @@ using System.Linq;
namespace ZicMoove.Model.Workflow
{
using Data;
using Interfaces;
using Musical;
using Social;
using YavscLib.Workflow;
public partial class Estimate : IEstimate
{
public long Id { get; set; }

View File

@ -3,8 +3,13 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ZicMoove.Pages.ClientPages.ActivityPage"
xmlns:local="clr-namespace:ZicMoove;assembly=ZicMoove"
xmlns:views="clr-namespace:ZicMoove.Views;assembly=ZicMoove"
xmlns:views="clr-namespace:ZicMoove.Views;assembly=ZicMoove"
xmlns:converters="clr-namespace:ZicMoove.Converters;assembly=ZicMoove"
>
<CarouselPage.Resources>
<ResourceDictionary>
</ResourceDictionary>
</CarouselPage.Resources>
<CarouselPage.ItemTemplate>
<DataTemplate>
<ContentPage>
@ -30,7 +35,7 @@
<ViewCell>
<ViewCell.View>
<StackLayout>
<Button Text="{Binding Title}" CommandParameter="{Binding Action}"/>
<Button Text="{Binding Title}" CommandParameter="{Binding ActionName}"/>
</StackLayout>
</ViewCell.View>
</ViewCell>

View File

@ -1,15 +1,20 @@

using ZicMoove.Interfaces;
using System;
using System;
namespace ZicMoove.Model.Workflow
{
public class BillingLine : IBillingLine
using YavscLib.Billing;
public class BillingLine : ICommandLine
{
public long Id { get; set; }
public string Description { get; set; }
public TimeSpan Duration { get; set; }
public int Count { get; set; } = 1;
public decimal UnitaryCost { get; set; }
public long EstimateId { get; set; }
}
}

View File

@ -79,6 +79,7 @@ namespace ZicMoove.Pages
ClientId = BookQuery.Client.UserId,
CommandId = BookQuery.Id,
OwnerId = MainSettings.CurrentUser.Id,
CommandType = "RdvQuery",
Id = 0
});
DataManager.Instance.EstimationCache.Add(editEstimateViewModel);

View File

@ -15,12 +15,6 @@ namespace ZicMoove.Pages
InitializeComponent();
foreach (string du in Enum.GetNames(typeof(BillingLineViewModel.DurationUnits)))
picker.Items.Add(du);
BindingContext = new BillingLineViewModel(new BillingLine());
}
public EditBillingLinePage()
{
Initialize();
}
public EditBillingLinePage(BillingLineViewModel model)

View File

@ -54,8 +54,9 @@ namespace ZicMoove.Pages
protected void OnNewCommanLine(object sender, EventArgs e)
{
var com = new BillingLine() { Count = 1, UnitaryCost = 0.01m };
var bill = ((EditEstimateViewModel)BindingContext).Bill;
var model = (EditEstimateViewModel)BindingContext;
var com = new BillingLine() { Count = 1, UnitaryCost = 0.01m, EstimateId = model.Data.Id };
var bill = model.Bill;
var lineView = new BillingLineViewModel(com)
{ ValidateCommand = new Command(() => {
bill.Add(new BillingLineViewModel(com));

View File

@ -79,7 +79,7 @@ namespace ZicMoove.Pages
};
OnInitMap();
/*
// A "relocate" button : useless, since it yet exists
// A "relocate" button :
var reLocate = new Button { Text = "Re-centrer" };
reLocate.Clicked += async delegate {

View File

@ -1,17 +1,19 @@

using ZicMoove.ViewModels.UserProfile;
using Plugin.Media;
using Plugin.Media;
using Plugin.Media.Abstractions;
using System;
using Xamarin.Forms;
using ZicMoove.Settings;
using ZicMoove.Helpers;
using System.Net.Http;
using Android.Graphics;
namespace ZicMoove.Pages.UserProfile
{
public partial class UserProfilePage
using ViewModels.UserProfile;
using Helpers;
using System.IO;
using System.Threading.Tasks;
using Android.Content.Res;
public partial class UserProfilePage
{
public UserProfilePage()
{
@ -28,62 +30,135 @@ namespace ZicMoove.Pages.UserProfile
BindingContext = model;
}
private async void BtnPay_Clicked(object sender, EventArgs e)
{
App.PlatformSpecificInstance.Pay(0.1, Interfaces.PayMethod.Immediate, "test payment");
}
private async void AvatarButton_Clicked(object sender, EventArgs e)
{
IsBusy = true;
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
await DisplayAlert("No Camera", ":( No camera avaialble.", "OK");
IsBusy = false;
return;
}
IsBusy = true;
var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
Directory = "Avatars",
Name = "me.jpg"
Name = "me.jpg",
DefaultCamera = CameraDevice.Front
});
if (file == null)
return;
using (var client = UserHelpers.CreateJsonClient())
{
// Get the whole data
try
IsBusy = false;
return;
}
if (TargetPlatform.Android == Device.OS)
{
// Rotate if needed
BitmapFactory.Options options = new BitmapFactory.Options { };
Android.Media.ExifInterface exif = new Android.Media.ExifInterface(file.Path);
var orientation = exif.GetAttributeInt(
Android.Media.ExifInterface.TagOrientation, 0);
using (var stream = file.GetStream())
{
using (var stream = file.GetStream())
{
var requestContent = new MultipartFormDataContent();
var content = new StreamContent(stream);
var filename = "me.jpg";
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
content.Headers.Add("Content-Disposition", $"form-data; name=\"file\"; filename=\"{filename}\"");
requestContent.Add(content, "file", filename);
var bmp = await BitmapFactory.DecodeStreamAsync(stream);
using (var response = await client.PostAsync(Constants.YavscApiUrl + "/setavatar", requestContent))
// Next we calculate the ratio that we need to resize the image by
// in order to fit the requested dimensions.
int outHeight = options.OutHeight;
int outWidth = options.OutWidth;
Matrix mtx = new Matrix();
Bitmap nbmp = null;
switch (orientation)
{
case (int)Orientation.Undefined: // Nexus 7 landscape...
mtx.PreRotate(180);
nbmp = Bitmap.CreateBitmap(bmp, 0, 0, bmp.Width, bmp.Height, mtx, false);
mtx.Dispose();
mtx = null;
break;
case (int)Orientation.Landscape:
break;
case 1: // landscape left
case 3: // Landskape right
mtx.PreRotate(180);
nbmp = Bitmap.CreateBitmap(bmp, 0, 0, bmp.Width, bmp.Height, mtx, false);
break;
case 6: // portrait
mtx.PreRotate(90);
nbmp = Bitmap.CreateBitmap(bmp, 0, 0, bmp.Width, bmp.Height, mtx, false);
break;
case 8: // my portrait
mtx.PreRotate(-90);
nbmp = Bitmap.CreateBitmap(bmp, 0, 0, bmp.Width, bmp.Height, mtx, false);
break;
}
if (nbmp != null)
{
using (var ostream = new MemoryStream())
{
if (response.IsSuccessStatusCode)
{
// TODO image update
var recnt = await response.Content.ReadAsStringAsync();
}
nbmp.Compress(Bitmap.CompressFormat.Png, 10, ostream);
ostream.Seek(0, SeekOrigin.Begin);
var ok = await SendAvatarStreamAsync(ostream);
}
nbmp.Dispose();
}
else
{
using (var ostream = new MemoryStream())
{
bmp.Compress(Bitmap.CompressFormat.Png, 10, ostream);
ostream.Seek(0, SeekOrigin.Begin);
var ok = await SendAvatarStreamAsync(ostream);
}
}
mtx.Dispose();
bmp.Dispose();
}
catch (Exception ex)
exif.Dispose();
options.Dispose();
}
else
{
using (var stream = file.GetStream())
{
// TODO error report
var ok = await SendAvatarStreamAsync(stream);
}
}
}
IsBusy = false;
}
private async Task<bool> SendAvatarStreamAsync(Stream stream)
{
using (var client = UserHelpers.CreateJsonClient())
{
var requestContent = new MultipartFormDataContent();
var content = new StreamContent(stream);
var filename = "me.jpg";
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
content.Headers.Add("Content-Disposition", $"form-data; name=\"file\"; filename=\"{filename}\"");
requestContent.Add(content, "file", filename);
using (var response = await client.PostAsync(Constants.YavscApiUrl + "/setavatar", requestContent))
{
if (response.IsSuccessStatusCode)
{
// TODO image update
var recnt = await response.Content.ReadAsStringAsync();
return true;
}
}
}
return false;
}
public void OnManageFiles(object sender, EventArgs e)
{
ShowPage<UserFiles>(null, true);

View File

@ -97,6 +97,15 @@ namespace ZicMoove {
}
}
/// <summary>
/// Recherche une chaîne localisée semblable à Carte.
/// </summary>
public static string Carte {
get {
return ResourceManager.GetString("Carte", resourceCulture);
}
}
/// <summary>
/// Recherche une chaîne localisée semblable à Annonces client.
/// </summary>
@ -125,7 +134,7 @@ namespace ZicMoove {
}
/// <summary>
/// Recherche une chaîne localisée semblable à La création a échoué, contenu envoyé: {stringContent} @ Uri: {ControllerUri.AbsoluteUri}: Erreur : {errcontent}.
/// Recherche une chaîne localisée semblable à La création a échoué, contenu envoyé: {0} @ Uri: {1}.
/// </summary>
public static string CreationFailed {
get {

View File

@ -124,7 +124,7 @@
<value>Annuler la validation</value>
</data>
<data name="CreationFailed" xml:space="preserve">
<value>La création a échoué, contenu envoyé: {stringContent} @ Uri: {ControllerUri.AbsoluteUri}: Erreur : {errcontent}</value>
<value>La création a échoué, contenu envoyé: {0} @ Uri: {1}</value>
</data>
<data name="DoEstimate" xml:space="preserve">
<value>Faire un devis</value>
@ -248,4 +248,7 @@
<data name="Street" xml:space="preserve">
<value>Rue</value>
</data>
<data name="Carte" xml:space="preserve">
<value>Carte</value>
</data>
</root>

View File

@ -1,15 +1,16 @@
using ZicMoove.Attributes;
using ZicMoove.Interfaces;
using ZicMoove.Model.Workflow;
using ZicMoove.ViewModels.Validation;

using System;
using System.Globalization;
using System.Windows.Input;
using System.ComponentModel;
using YavscLib.Billing;
namespace ZicMoove.ViewModels.EstimateAndBilling
{
public class BillingLineViewModel : EditingViewModel<BillingLine>, IBillingLine
using Attributes;
using Model.Workflow;
using Validation;
public class BillingLineViewModel : EditingViewModel<BillingLine>, ICommandLine
{
public ICommand RemoveCommand { get; set; }
public ICommand ValidateCommand { set; get; }
@ -67,6 +68,34 @@ namespace ZicMoove.ViewModels.EstimateAndBilling
Data.Count = count;
}
}
private long estimateId;
public long EstimateId
{
get
{
return estimateId;
}
set
{
SetProperty<long>(ref estimateId, value);
Data.EstimateId = estimateId;
}
}
private long id;
public long Id
{
get
{
return id;
}
set
{
SetProperty<long>(ref id, value);
Data.Id = id;
}
}
private string description;
public string Description
{

View File

@ -21,15 +21,20 @@ namespace ZicMoove.ViewModels.Messaging
public ConnectionState State
{
get { return state; }
set
{
SetProperty<ConnectionState>(ref state, value);
}
}
public ChatViewModel()
{
App.ChatHubConnection.StateChanged += ChatHubConnection_StateChanged;
MainSettings.UserChanged += MainSettings_UserChanged;
Messages = new ObservableCollection<ChatMessage>();
Notifs = new ObservableCollection<ChatMessage>();
ChatUsers = DataManager.Instance.ChatUsers;
State = App.ChatHubConnection.State;
App.ChatHubConnection.StateChanged += ChatHubConnection_StateChanged;
MainSettings.UserChanged += MainSettings_UserChanged;
App.ChatHubProxy.On<string, string>("addMessage", (n, m) =>
{
Messages.Add(new ChatMessage
@ -93,7 +98,7 @@ namespace ZicMoove.ViewModels.Messaging
private void ChatHubConnection_StateChanged(StateChange obj)
{
SetProperty<ConnectionState>(ref state, obj.NewState, "State");
State = obj.NewState;
}
}
}

View File

@ -48,8 +48,8 @@ namespace ZicMoove.ViewModels.UserProfile
}
set
{
MainSettings.AllowGPSUsage = value;
SetProperty<bool>(ref allowUseMyPosition, value);
MainSettings.AllowGPSUsage = value;
}
}
@ -62,8 +62,8 @@ namespace ZicMoove.ViewModels.UserProfile
}
set
{
MainSettings.AllowProBookingOnly = value;
SetProperty<bool>(ref allowUseMyPosition, value);
MainSettings.AllowProBookingOnly = value;
}
}
bool receivePushNotifications = MainSettings.PushNotifications;
@ -75,8 +75,8 @@ namespace ZicMoove.ViewModels.UserProfile
}
set
{
MainSettings.PushNotifications = value;
SetProperty<bool>(ref receivePushNotifications, value);
MainSettings.PushNotifications = value;
}
}
private long queryCount;

View File

@ -185,8 +185,6 @@
<Compile Include="Interfaces\IViewFactory.cs" />
<Compile Include="Model\Workflow\ClientProviderInfo.cs" />
<Compile Include="Interfaces\IBookQueryData.cs" />
<Compile Include="Interfaces\IBillingLine.cs" />
<Compile Include="Interfaces\IEstimate.cs" />
<Compile Include="Pages\BlogPages\BlogPage.cs" />
<Compile Include="Pages\EstimatePages\BookQueriesPage.xaml.cs">
<DependentUpon>BookQueriesPage.xaml</DependentUpon>