Commit 363d5a57 by Javier Piris

Creados y añadido modelo nuevo de datos + CustomCells nuevas, un selector…

Creados y añadido modelo nuevo de datos + CustomCells nuevas, un selector template y la adaptación para la vista de nueva consulta + Adaptación delos viewmodels de preguntas al nuevo modelo
parent 88f1509e
using MvvmHelpers;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
namespace inutralia.Models.Questions
{
[JsonObject(MemberSerialization.OptIn)]
[DataPath("messages")]
public class Message : ObservableEntityData
{
public enum Estatus
{
Pending,
Answered_for_client,
Answered_for_nutricionist,
Closed
}
public string StatusImg => imgStatus[StateId];
[JsonProperty("text", Required = Required.Always)]
public string Text
{
get { return _text; }
set { SetProperty(ref _text, value); }
}
string _text;
[JsonProperty("datetime", Required = Required.Always)]
public DateTime MessageDateTime
{
get { return _messageDateTime; }
set { SetProperty(ref _messageDateTime, value); }
}
DateTime _messageDateTime;
public string TimeDisplay => MessageDateTime.ToLocalTime().ToString();
[JsonProperty("isText", Required = Required.Always)]
public bool IsTextIn
{
get { return _isTextIn; }
set { SetProperty(ref _isTextIn, value); }
}
bool _isTextIn;
[JsonProperty("state_id", Required = Required.Always)]
public int StateId { get; set; }
[JsonProperty("status", Required = Required.Always)]
[JsonConverter(typeof(StringEnumConverter))]
public Estatus State { get; set; }
[JsonProperty("subject", Required = Required.Always)]
public string Subject
{
get { return _subject; }
set { SetProperty(ref _subject, value); }
}
string _subject;
string[] imgStatus = new string[2]
{
"pendiente.png", // 1 - Pendiente de responder
//"respondida_por_cliente.png", // 2 - Respondida por cliente
//"respondida_por_nutricionista", // 3- Respondida por nutricionista
"cerrada" // 4 - Conversación cerrada
};
}
}
\ No newline at end of file
......@@ -29,6 +29,7 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Compile Include="Questions\Message.cs" />
<Compile Include="Utils\BoolConverter.cs" />
<Compile Include="Menu\LocalMenu.cs" />
<Compile Include="Menu\MenuBase.cs" />
......@@ -37,8 +38,6 @@
<Compile Include="Profile\Profile.cs" />
<Compile Include="Menu\Ingredient.cs" />
<Compile Include="Menu\Menu.cs" />
<Compile Include="Questions\QuestionMessage.cs" />
<Compile Include="Questions\QuestionSpecialist.cs" />
<Compile Include="Recipe\Recipe.cs" />
<Compile Include="Recipe\RecipeOption.cs" />
<Compile Include="Recipe\RecipeOptionGroup.cs" />
......
using inutralia.CustomCells;
using inutralia.Models.Questions;
using Xamarin.Forms;
namespace inutralia
{
public class SelectorDataTemplate : DataTemplateSelector
{
private readonly DataTemplate textInDataTemplate;
private readonly DataTemplate textOutDataTemplate;
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
var messageVm = item as Message;
if (messageVm == null)
return null;
return messageVm.IsTextIn ? this.textInDataTemplate : this.textOutDataTemplate;
}
public SelectorDataTemplate()
{
this.textInDataTemplate = new DataTemplate(typeof(TextInViewCell));
this.textOutDataTemplate = new DataTemplate(typeof(TextOutViewCell));
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="inutralia.CustomCells.TextInViewCell">
<Grid ColumnSpacing="2" Padding="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Frame Grid.Row="0" Grid.Column="1" BackgroundColor="#0535f0" CornerRadius="15">
<Frame.HasShadow>
<OnPlatform x:TypeArguments="x:Boolean" iOS="false" Android="true"/>
</Frame.HasShadow>
<StackLayout>
<Label TextColor="White" Text="{Binding Text}" />
</StackLayout>
</Frame>
<Label FontSize="Micro" Grid.Row="1" Grid.Column="1" Text="{Binding MessageDateTime, StringFormat='{0:MM/dd/yyyy hh:mm tt}'}" TextColor="Gray"></Label>
</Grid>
</ViewCell>
\ No newline at end of file
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace inutralia.CustomCells
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class TextInViewCell : ViewCell
{
public TextInViewCell()
{
InitializeComponent();
}
}
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="inutralia.CustomCells.TextOutViewCell">
<Grid ColumnSpacing="2" Padding="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="2"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Frame Grid.Row="0" Grid.Column="1" CornerRadius="15">
<Frame.HasShadow>
<OnPlatform x:TypeArguments="x:Boolean" Android="true" iOS="True"/>
</Frame.HasShadow>
<Frame.BackgroundColor>
<OnPlatform x:TypeArguments="Color" Android="White" iOS="#F5F5F5"/>
</Frame.BackgroundColor>
<StackLayout>
<Label TextColor="Black" Text="{Binding Text}" />
</StackLayout>
</Frame>
<Label Grid.Row="1" FontSize="Micro" Grid.Column="1" HorizontalTextAlignment="End" Text="{Binding MessageDateTime, StringFormat='{0:MM/dd/yyyy hh:mm tt}'}" TextColor="Gray"></Label>
</Grid>
</ViewCell>
\ No newline at end of file
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace inutralia.CustomCells
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class TextOutViewCell : ViewCell
{
public TextOutViewCell()
{
InitializeComponent();
}
}
}
\ No newline at end of file
using inutralia.Models;
using inutralia.Models.Questions;
using MvvmHelpers;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using System;
using System.Windows.Input;
using Xamarin.Forms;
namespace inutralia.ViewModels
{
public class NewQuestionViewModel : BaseNavigationViewModel
public class NewQuestionViewModel : BaseViewModel
{
public enum Estatus
{
Pending,
Answered_for_client,
Answered_for_nutricionist,
Closed
}
public QuestionSpecialist QuestionSpecialist { private set; get; }
public Estatus State => (Estatus)QuestionSpecialist?.Id;
public ObservableRangeCollection<QuestionMessage> _NewQuestion;
// Comando de update del listado
Command _RefreshNewQuestionCommand;
// Comando de borrado de elemento
Command _DeleteNewQuestionCommand;
public NewQuestionViewModel(QuestionSpecialist quest)
{
QuestionSpecialist = quest;
Title = QuestionSpecialist.Subject;
if (quest.Messages.Count() > 0)
{
NewQuestion = new ObservableRangeCollection<QuestionMessage>(quest.Messages);
}
else
{
NewQuestion = new ObservableRangeCollection<QuestionMessage>();
}
}
// Acceso a la lista de PREGUNTAS
public ObservableRangeCollection<QuestionMessage> NewQuestion
{
// Getter (lazy load), crea la lista si no existe
get { return _NewQuestion ?? (_NewQuestion = new ObservableRangeCollection<QuestionMessage>()); }
// Setter. Cambia el valor y notifica a la vista de dicho cambio
set
{
_NewQuestion = value;
OnPropertyChanged("NewQuestion");
}
}
public async Task RefreshData()
{
if (QuestionSpecialist == null || (QuestionSpecialist.Id < 0))
return;
IsBusy = true;
public ObservableRangeCollection<Message> ListMessages { get; }
public ICommand SendCommand { get; set; }
if (await App.API.RefreshItemAsync(QuestionSpecialist))
{
Title = QuestionSpecialist.StatusImg;
OnPropertyChanged("State");
}
IsBusy = false;
await FetchQuestions();
}
///<summary>
/// Método que realiza la carga inicial del listado
///</summary>
public async Task ExecuteLoadNewQuestionCommand()
public NewQuestionViewModel()
{
///Realiza el procesp de actualización si hay menos
///de un elemento en el listado
if (QuestionSpecialist.Messages.Count() < 1)
await FetchQuestions();
}
/// <summary>
/// Acceso al comando de actualización del listado
/// </summary>
public Command RefreshNewQuestionCommand
{
// Getter (lazy load), crea el comando si no existe
get { return _RefreshNewQuestionCommand ?? (_RefreshNewQuestionCommand = new Command(async () => await ExecuteRefreshQuestionMessagesCommand())); }
}
ListMessages = new ObservableRangeCollection<Message>();
/// <summary>
/// Proceso de ejecución del comando de actualización del listado
/// </summary>
public async Task ExecuteRefreshQuestionMessagesCommand()
{
try
{
// Hace que el comando no se pueda ejecutar de nuevo
RefreshNewQuestionCommand.ChangeCanExecute();
// Realiza el proceso de actualización
await FetchQuestions();
// Hace que el comando pueda volver a ejecutarse
RefreshNewQuestionCommand.ChangeCanExecute();
}
catch (System.Exception e)
SendCommand = new Command(() =>
{
string err = e.Message;
}
}
///<summary>
///Proceso de actualización del listado
///</summary>
async Task FetchQuestions()
{
// Indicamos que estámos ocupados (provoca que aparezca el indicador de carga)
IsBusy = true;
// Llamada al API para coger el listado (provoca que se actualize la vista del listado)
try
{
if (await App.API.RefreshItemAsync(QuestionSpecialist) == true)
if (!String.IsNullOrWhiteSpace(OutText))
{
Title = QuestionSpecialist.Subject;
NewQuestion = new ObservableRangeCollection<QuestionMessage>(QuestionSpecialist.Messages);
}
}
catch (System.Exception e)
{
string err = e.Message;
NewQuestion.Clear();
}
// Indicamos que ya no estámos ocupados (provoca que desaparezca el indicador de carga)
IsBusy = false;
}
///<summary>
///Acceso al comando de borrado de pregunta
///</summary>
public Command DeleteQuestionCommand
{
// Getter (lazy load), crea el comando si no existe. Nótese que, a diferencia del comando
// de Refresh, éste recibe una notificación como parámetro
get
{
return _DeleteNewQuestionCommand ?? (_DeleteNewQuestionCommand = new Command(async (parameter) => await ExecuteDeleteQuestionCommand(parameter as QuestionMessage)));
}
}
///<summary>
///Proceso de ejecución de comando de borrado
///</summary>
///<param name="messag"></param>
///<returns></returns>
async Task ExecuteDeleteQuestionCommand(QuestionMessage messag)
{
// Verificar parámetro
if (messag != null)
{
// Indicamos que estámos ocupados (provoca que aparezca el indicador de carga)
IsBusy = true;
// Llamamos al API para borrar el mensaje
await App.API.DeleteItemAsync(messag);
var message = new Message
{
Text = OutText,
IsTextIn = false,
MessageDateTime = DateTime.Now
};
//Actualizamos la lista
await FetchQuestions();
//Indicamos que no estámos ocupados (provoca que desarparezca el indicador de carga)
IsBusy = false;
}
}
///<summary>
///Guarda un mensaje perteneciente a QuestionSpecialist ya sea una pregunta nueva, nuevo mensaje o edición
///</summary>
///<param name="text"></param>
///<returns></returns>
public async Task SaveQuestion(string text)
{
var q = QuestionSpecialist;
HttpMethod method = HttpMethod.Post;
IsBusy = true;
if (q.Id < 0)
{
var data = new Dictionary<string, string>()
{
{"subject", q.Subject }, {"message", text}
};
// New Question
await App.API.RawMessage(method, string.Format("questions"), data, q);
}
else
{
QuestionMessage msg;
if (q.State == QuestionSpecialist.Estatus.Closed)
{
//Edit last Message
msg = q.Messages.Last();
method = HttpMethod.Put;
ListMessages.Add(message);
OutText = "";
}
else
{
//Add new Message
msg = new QuestionMessage();
} //endif
msg.Text = text;
await App.API.RawMessage(method, string.Format("questions/{0}", q.Id), msg, q);
} // endif
IsBusy = false;
NewQuestion = new ObservableRangeCollection<QuestionMessage>(QuestionSpecialist.Messages);
});
}
///<summary>
///Actualiza una pregunta
///</summary>
///<returns></returns>
public async Task SaveQuestion()
{
var q = QuestionSpecialist;
HttpMethod method = HttpMethod.Post;
IsBusy = true;
await App.API.UpdateItemAsync(q);
if (await App.API.RefreshItemAsync(QuestionSpecialist))
{
Title = QuestionSpecialist.StatusImg;
OnPropertyChanged("State");
}
IsBusy = false;
public string OutText
{
get { return _outText; }
set { SetProperty(ref _outText, value); }
}
public bool IsCloseOrPending => (State == Estatus.Answered_for_client || State == Estatus.Answered_for_nutricionist || State == Estatus.Pending || State == Estatus.Closed) && QuestionSpecialist.Messages.Count() > 0 || State == Estatus.Answered_for_nutricionist;
public bool MayBeClosed => !IsCloseOrPending;
string _outText = string.Empty;
}
}
using System.Threading.Tasks;
using inutralia.Models;
using inutralia.Models.Questions;
namespace inutralia.ViewModels
{
......@@ -13,31 +14,31 @@ namespace inutralia.ViewModels
Cerrado = 4
}
public PendingReadViewModel(QuestionSpecialist questionSpecialist)
public PendingReadViewModel(Message message)
{
QuestionSpecialist = questionSpecialist;
Message = message;
Title = QuestionSpecialist?.StatusImg;
Title = message?.StatusImg;
}
public PendingReadViewModel() { }
public QuestionSpecialist QuestionSpecialist { private set; get; }
public Message Message { private set; get; }
public int StateId => QuestionSpecialist.StateId;
public int StateId => Message.StateId;
public Estatus estatus => (Estatus)QuestionSpecialist?.StateId;
public Estatus estatus => (Estatus)Message?.StateId;
public async Task RefresData()
{
if (QuestionSpecialist == null)
if (Message == null)
return;
IsBusy = true;
if (await App.API.RefreshItemAsync(QuestionSpecialist))
if (await App.API.RefreshItemAsync(Message))
{
Title = QuestionSpecialist.StatusImg;
Title = Message.StatusImg;
OnPropertyChanged("");
}
......
using inutralia.Models;
using inutralia.Models.Questions;
using MvvmHelpers; // Este namespace está en el paquete Refractored.MvvmHelpers
using System;
using System.Threading.Tasks;
......@@ -14,7 +15,7 @@ namespace inutralia.ViewModels
public QuestionListViewModel() { }
// Datos del histórico
ObservableRangeCollection<QuestionSpecialist> _QuestionList;
ObservableRangeCollection<Message> _QuestionList;
// Comando de loading del listado
Command _LoadQuestionListCommand;
......@@ -23,10 +24,10 @@ namespace inutralia.ViewModels
Command _RefreshQuestionListCommand;
// Acceso a la lista preguntas
public ObservableRangeCollection<QuestionSpecialist> QuestionList
public ObservableRangeCollection<Message> QuestionList
{
// Getter (lazy load), crea la lista si no exite
get => _QuestionList ?? (_QuestionList = new ObservableRangeCollection<QuestionSpecialist>());
get => _QuestionList ?? (_QuestionList = new ObservableRangeCollection<Message>());
// Setter. Cambia el valor y notifica a la vista de dicho cambio
set
......@@ -97,7 +98,7 @@ namespace inutralia.ViewModels
// la notificación (campo Body)
try
{
QuestionList = new ObservableRangeCollection<QuestionSpecialist>(await App.API.RefreshListAsync<QuestionSpecialist>());
QuestionList = new ObservableRangeCollection<Message>(await App.API.RefreshListAsync<Message>());
}
catch (Exception e)
{
......
using inutralia.Models;
using inutralia.Models.Questions;
using inutralia.ViewModels;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
......@@ -18,7 +19,7 @@ namespace inutralia.Views.Question
protected async void ItemTapped(object sender, ItemTappedEventArgs e)
{
var respon = e.Item as QuestionSpecialist;
var respon = e.Item as Message;
if (respon.StatusImg == "Respondida")
{
await DisplayAlert("ERROR", "La pregunta ya está respondida", "Entendido");
......@@ -28,7 +29,7 @@ namespace inutralia.Views.Question
await Navigation.PushAsync(
new PendingReadView()
{
BindingContext = new PendingReadViewModel((QuestionSpecialist)e.Item)
BindingContext = new PendingReadViewModel((Message)e.Item)
}
);
((ListView)sender).SelectedItem = null;
......
......@@ -2,181 +2,51 @@
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:artina="clr-namespace:UXDivers.Artina.Shared;assembly=UXDivers.Artina.Shared"
xmlns:local="clr-namespace:inutralia"
x:Class="inutralia.Views.Question.NewConsultationView"
x:Name="newConsultationView"
Title="Nueva Consulta"
Icon="Add1"
BackgroundColor="{DynamicResource BasePageColor}"
>
NavigationPage.HasBackButton="True">
<ContentPage.Content>
<StackLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<StackLayout VerticalOptions="FillAndExpand" Margin="10,15,10,15">
<ListView ItemsSource="{Binding NewQuestion}"
ItemTapped="ItemTapped"
IsPullToRefreshEnabled="True"
RefreshCommand="{Binding RefreshNewQuestionCommand}"
IsRefreshing="{Binding IsBusy, Mode=TwoWay}"
BackgroundColor="Transparent"
CachingStrategy="RecycleElement"
Footer=""
HasUnevenRows="True"
x:Name="listNewConsultation">
<!--Aquí se configura el template para cada elemento de la lista-->
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<!--Aquí comienza la definición visual de cada elemento de la lista. Se utiliza un Frame (implica borde redondeado)
dentro del cual va el icono con la notificación seguido del título de la misma-->
<StackLayout Orientation="Horizontal" VerticalOptions="FillAndExpand">
<Image Source="user_chat.png" VerticalOptions="CenterAndExpand" HorizontalOptions="Fill" IsVisible="{Binding FromUser}">
<Image.WidthRequest>
<OnIdiom x:TypeArguments="x:Double"
Phone="50"
Tablet="100"/>
</Image.WidthRequest>
<Image.HeightRequest>
<OnIdiom x:TypeArguments="x:Double"
Phone="50"
Tablet="100"/>
</Image.HeightRequest>
</Image>
<ContentView VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" IsVisible="{Binding FromUser}" BackgroundColor="{DynamicResource BasePageColor}">
<StackLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<StackLayout Style="{StaticResource ChatMessageEntryStyle}">
<Label Text="{Binding Text}" HorizontalOptions="StartAndExpand" TextColor="Black">
<Label.FontSize>
<OnIdiom x:TypeArguments="x:Double"
Phone="15"
Tablet="35"/>
</Label.FontSize>
</Label>
</StackLayout>
</StackLayout>
</ContentView>
<ContentView VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" IsVisible="{Binding FromExpert}" BackgroundColor="{DynamicResource BasePageColor}">
<StackLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<StackLayout Style="{StaticResource ChatMessageEntryStyle }">
<Label Text="{Binding Text}" HorizontalOptions="StartAndExpand" TextColor="Black">
<Label.FontSize>
<OnIdiom x:TypeArguments="x:Double"
Phone="15"
Tablet="35"/>
</Label.FontSize>
</Label>
</StackLayout>
</StackLayout>
</ContentView>
<Image Source="nutricionist_chat.png" VerticalOptions="CenterAndExpand" HorizontalOptions="Fill" IsVisible="{Binding FromExpert}">
<Image.WidthRequest>
<OnIdiom x:TypeArguments="x:Double"
Phone="50"
Tablet="100"/>
</Image.WidthRequest>
<ContentPage.Resources>
<ResourceDictionary>
<local:SelectorDataTemplate x:Key="MessageTemplateSelector"/>
</ResourceDictionary>
</ContentPage.Resources>
<Image.HeightRequest>
<OnIdiom x:TypeArguments="x:Double"
Phone="50"
Tablet="100"/>
</Image.HeightRequest>
</Image>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
<StackLayout Orientation="Horizontal" VerticalOptions="End" Margin="10,0,10,0">
<Entry x:Name="newQuest" Placeholder="Escriba su pregunta" HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand">
<Entry.HeightRequest>
<OnIdiom x:TypeArguments="x:Double">
<OnIdiom.Phone>
<OnPlatform x:TypeArguments="x:Double"
iOS="40"
Android="48"/>
</OnIdiom.Phone>
<OnIdiom.Tablet>
<OnPlatform x:TypeArguments="x:Double"
iOS="70"
Android="65"/>
</OnIdiom.Tablet>
</OnIdiom>
</Entry.HeightRequest>
<Entry.FontSize>
<OnIdiom x:TypeArguments="x:Double">
<OnIdiom.Phone>
<OnPlatform x:TypeArguments="x:Double"
iOS="25"
Android="17"/>
</OnIdiom.Phone>
<OnIdiom.Tablet>
<OnPlatform x:TypeArguments="x:Double"
iOS="40"
Android="40"/>
</OnIdiom.Tablet>
</OnIdiom>
</Entry.FontSize>
</Entry>
<artina:Button x:Name="buttonNewQuestion"
Image="btn_enviar_chat.png"
HorizontalOptions="End"
VerticalOptions="CenterAndExpand"
Style="{DynamicResource PrimaryActionButtonStyle}"
Clicked="ButtonNewQuestion_Clicked"
>
<Button.HeightRequest>
<OnIdiom x:TypeArguments="x:Double">
<OnIdiom.Phone>
<OnPlatform x:TypeArguments="x:Double"
iOS="40"
Android="48"/>
</OnIdiom.Phone>
<OnIdiom.Tablet>
<OnPlatform x:TypeArguments="x:Double"
iOS="70"
Android="65"/>
</OnIdiom.Tablet>
</OnIdiom>
</Button.HeightRequest>
<Button.WidthRequest>
<OnIdiom x:TypeArguments="x:Double">
<OnIdiom.Phone>
<OnPlatform x:TypeArguments="x:Double"
iOS="40"
Android="48"/>
</OnIdiom.Phone>
<OnIdiom.Tablet>
<OnPlatform x:TypeArguments="x:Double"
iOS="100"
Android="65"/>
</OnIdiom.Tablet>
</OnIdiom>
</Button.WidthRequest>
</artina:Button>
<ContentPage.Content>
<Grid RowSpacing="0" ColumnSpacing="0" >
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ScrollView>
<ListView x:Name="MessagesListView"
ItemTemplate="{StaticResource MessageTemplateSelector}"
ItemsSource="{Binding ListMessages}"
HasUnevenRows="True"
SeparatorVisibility="None"
Footer=""
/>
</ScrollView>
<StackLayout Orientation="Horizontal" Grid.Row="1" BackgroundColor="White" Padding="0,0,0,10">
<Entry HorizontalOptions="FillAndExpand"
Placeholder=" Escriba aquí su mensaje"
Text="{Binding OutText}"
Keyboard="Chat"
Margin="4"/>
<Image Source="btn_enviar_chat.png" WidthRequest="45" HeightRequest="5" Margin="4" BackgroundColor="#FFA2C300">
<Image.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding SendCommand}" />
</Image.GestureRecognizers>
</Image>
</StackLayout>
</StackLayout>
</Grid>
</ContentPage.Content>
</ContentPage>
\ No newline at end of file
......@@ -10,15 +10,26 @@ namespace inutralia.Views.Question
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class NewConsultationView : ContentPage
{
protected NewQuestionViewModel ViewModel => BindingContext as NewQuestionViewModel;
//protected NewQuestionViewModel ViewModel => BindingContext as NewQuestionViewModel;
NewQuestionViewModel vm;
public NewConsultationView()
{
InitializeComponent();
newQuest.IsEnabled = true;
buttonNewQuestion.IsEnabled = false;
buttonNewQuestion.Clicked += ButtonNewQuestion_Clicked;
BindingContext = vm = new NewQuestionViewModel();
vm.ListMessages.CollectionChanged += (sender, e) =>
{
var target = vm.ListMessages[vm.ListMessages.Count - 1];
MessagesListView.ScrollTo(target, ScrollToPosition.End, true);
};
//newQuest.IsEnabled = true;
//buttonNewQuestion.IsEnabled = false;
//buttonNewQuestion.Clicked += ButtonNewQuestion_Clicked;
}
//protected override void OnBindingContextChanged()
......@@ -32,28 +43,28 @@ namespace inutralia.Views.Question
// OnDataRefreshed();
//}
private async void ButtonNewQuestion_Clicked(object sender, EventArgs e)
{
if (String.IsNullOrWhiteSpace(newQuest.Text))
{
newQuest.Text = "";
return;
}
//private async void ButtonNewQuestion_Clicked(object sender, EventArgs e)
//{
// if (String.IsNullOrWhiteSpace(newQuest.Text))
// {
// newQuest.Text = "";
// return;
// }
await ViewModel.SaveQuestion(newQuest.Text);
listNewConsultation.SelectedItem = null;
//OnDataRefreshed();
}
// await ViewModel.SaveQuestion(newQuest.Text);
// listNewConsultation.SelectedItem = null;
// //OnDataRefreshed();
//}
///// <summary>
///// Método llamado cada vez que una página pasa a ser visible
///// </summary>
protected override async void OnAppearing()
{
base.OnAppearing();
//await ViewModel.RefreshData();
//OnDataRefreshed();
}
//protected override async void OnAppearing()
//{
// base.OnAppearing();
// await ViewModel.RefreshData();
// OnDataRefreshed();
//}
///// <summary>
///// Método llamado al hacer tap en un elemento de la lista. Navega a la página de detalle
......@@ -61,22 +72,22 @@ namespace inutralia.Views.Question
///// </summary>
///// <param name="sender">La ListiView</param>
///// <param name="e">Argumentos del evento</param>
void ItemTapped(object sender, ItemTappedEventArgs e)
{
if (e == null) return; // has been set to null, do not 'process' tapped event
//void ItemTapped(object sender, ItemTappedEventArgs e)
//{
// if (e == null) return; // has been set to null, do not 'process' tapped event
QuestionMessage item = (QuestionMessage)e.Item;
if (ViewModel.NewQuestion.Last() == item && item.FromUser)
{
buttonNewQuestion.IsEnabled = true;
newQuest.IsEnabled = true;
newQuest.Text = item.Text;
}
else
{
((ListView)sender).SelectedItem = null; // de-select the row
}
}
// QuestionMessage item = (QuestionMessage)e.Item;
// if (ViewModel.NewQuestion.Last() == item && item.FromUser)
// {
// buttonNewQuestion.IsEnabled = true;
// newQuest.IsEnabled = true;
// newQuest.Text = item.Text;
// }
// else
// {
// ((ListView)sender).SelectedItem = null; // de-select the row
// }
//}
//private void OnDataRefreshed()
//{
......
using inutralia.Models;
using inutralia.Models.Questions;
using inutralia.ViewModels;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
......@@ -10,7 +11,7 @@ namespace inutralia.Views.Question
{
protected PendingReadViewModel ViewModel => BindingContext as PendingReadViewModel;
public QuestionSpecialist QuestionSpecialist { private set; get; }
public Message Message { private set; get; }
public PendingReadView()
{
......
......@@ -37,6 +37,13 @@
<Compile Include="API\LocalDataService.cs" />
<Compile Include="Converters\ImageTransformator.cs" />
<Compile Include="Converters\AlternatingBackgroundColorConverter.cs" />
<Compile Include="CustomCells\SelectorDataTemplate.cs" />
<Compile Include="CustomCells\TextInViewCell.xaml.cs">
<DependentUpon>TextInViewCell.xaml</DependentUpon>
</Compile>
<Compile Include="CustomCells\TextOutViewCell.xaml.cs">
<DependentUpon>TextOutViewCell.xaml</DependentUpon>
</Compile>
<Compile Include="Helpers\Settings.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="App.xaml.cs">
......@@ -275,7 +282,6 @@
<SubType>Designer</SubType>
</None>
<None Include="SampleData.json" />
<None Include="Gorilla.json" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Views\Recipe\ItemList\RecipeItemTemplate.xaml">
......@@ -480,6 +486,18 @@
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="CustomCells\TextInViewCell.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="CustomCells\TextOutViewCell.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment