Commit 30de29e9 by Javier Piris

Refactor de la app de INutralia

parent 4ad2307a
namespace inutralia.Abstractions
{
/// <summary>
/// A service that exposes whether or not certain device capabilities are available.
/// </summary>
public interface ICapabilityService
{
/// <summary>
/// Gets a bool representing whether or not the device can make calls.
/// </summary>
/// <value>A bool representing whether or not the device can make calls.</value>
bool CanMakeCalls { get; }
/// <summary>
/// A service that exposes whether or not certain device capabilities are available.
/// </summary>
public interface ICapabilityService
{
/// <summary>
/// Gets a bool representing whether or not the device can make calls.
/// </summary>
/// <value>A bool representing whether or not the device can make calls.</value>
bool CanMakeCalls { get; }
/// <summary>
/// Gets a bool representing whether or not the device can send messages.
/// </summary>
/// <value>A bool representing whether or not the device can send messages.</value>
bool CanSendMessages { get; }
/// <summary>
/// Gets a bool representing whether or not the device can send messages.
/// </summary>
/// <value>A bool representing whether or not the device can send messages.</value>
bool CanSendMessages { get; }
/// <summary>
/// Gets a bool representing whether or not the device cansend email.
/// </summary>
/// <value>A bool representing whether or not the device cansend email.</value>
bool CanSendEmail { get; }
}
/// <summary>
/// Gets a bool representing whether or not the device cansend email.
/// </summary>
/// <value>A bool representing whether or not the device cansend email.</value>
bool CanSendEmail { get; }
}
}
......@@ -3,50 +3,50 @@ using System.Threading.Tasks;
namespace inutralia.Abstractions
{
/// <summary>
/// Interfaz genérico de almacenamiento de entidades
/// </summary>
public interface IDataPersistenceService
{
/// <summary>
/// Recupera de forma asíncrona los datos de una entidad a partir de su
/// identificador
/// </summary>
/// <typeparam name="T">Tipo de dato de cada entidad</typeparam>
/// <param name="id">Identificador de la entidad</param>
/// <returns>Instancia de T correspondiente al identificador</returns>
Task<T> GetItemAsync<T>(int id) where T : IIdentifiableEntity;
/// <summary>
/// Interfaz genérico de almacenamiento de entidades
/// </summary>
public interface IDataPersistenceService
{
/// <summary>
/// Recupera de forma asíncrona los datos de una entidad a partir de su
/// identificador
/// </summary>
/// <typeparam name="T">Tipo de dato de cada entidad</typeparam>
/// <param name="id">Identificador de la entidad</param>
/// <returns>Instancia de T correspondiente al identificador</returns>
Task<T> GetItemAsync<T>(int id) where T : IIdentifiableEntity;
/// <summary>
/// Obtiene de forma asíncrona una lista de entidades
/// </summary>
/// <typeparam name="T">Tipo de dato de cada entidad</typeparam>
/// <returns>Lista de elementos obtenidos</returns>
Task<List<T>> RefreshListAsync<T>() where T : IIdentifiableEntity;
/// <summary>
/// Obtiene de forma asíncrona una lista de entidades
/// </summary>
/// <typeparam name="T">Tipo de dato de cada entidad</typeparam>
/// <returns>Lista de elementos obtenidos</returns>
Task<List<T>> RefreshListAsync<T>() where T : IIdentifiableEntity;
/// <summary>
/// Recupera de forma asíncrona los datos de una entidad
/// </summary>
/// <typeparam name="T">Tipo de dato de la entidad</typeparam>
/// <param name="item">La entidad a actualizar</param>
/// <returns>Si la operación se realizó correctamente</returns>
Task<bool> RefreshItemAsync<T>(T item) where T : IIdentifiableEntity;
/// <summary>
/// Recupera de forma asíncrona los datos de una entidad
/// </summary>
/// <typeparam name="T">Tipo de dato de la entidad</typeparam>
/// <param name="item">La entidad a actualizar</param>
/// <returns>Si la operación se realizó correctamente</returns>
Task<bool> RefreshItemAsync<T>(T item) where T : IIdentifiableEntity;
/// <summary>
/// Actualiza de forma asíncrona los datos de una entidad
/// </summary>
/// <typeparam name="T">Tipo de dato de la entidad</typeparam>
/// <param name="item">La entidad a actualizar</param>
/// <param name="isNew">Indica si hay que crear una entidad nueva o modificar una existente</param>
/// <returns>El ID de la entidad. Null en caso de error</returns>
Task<int?> UpdateItemAsync<T>(T item, bool isNew = false) where T : IIdentifiableEntity;
/// <summary>
/// Actualiza de forma asíncrona los datos de una entidad
/// </summary>
/// <typeparam name="T">Tipo de dato de la entidad</typeparam>
/// <param name="item">La entidad a actualizar</param>
/// <param name="isNew">Indica si hay que crear una entidad nueva o modificar una existente</param>
/// <returns>El ID de la entidad. Null en caso de error</returns>
Task<int?> UpdateItemAsync<T>(T item, bool isNew = false) where T : IIdentifiableEntity;
/// <summary>
/// Elimina de forma asíncrona una entidad
/// </summary>
/// <typeparam name="T">Tipo de dato de la entidad</typeparam>
/// <param name="item">La entidad a eliminar</param>
/// <returns>Si la operación se realizó correctamente</returns>
Task<bool> DeleteItemAsync<T>(T item) where T : IIdentifiableEntity;
}
/// <summary>
/// Elimina de forma asíncrona una entidad
/// </summary>
/// <typeparam name="T">Tipo de dato de la entidad</typeparam>
/// <param name="item">La entidad a eliminar</param>
/// <returns>Si la operación se realizó correctamente</returns>
Task<bool> DeleteItemAsync<T>(T item) where T : IIdentifiableEntity;
}
}
namespace inutralia.Abstractions
{
/// <summary>
/// A service that exposes some platform environment characteristics.
/// </summary>
public interface IEnvironmentService
{
/// <summary>
/// Gets a bool representing whether or not is the app is running on a simulator or device.
/// </summary>
/// <value>True if the device is real, false if a simulator/emulator.</value>
bool IsRealDevice { get; }
}
/// <summary>
/// A service that exposes some platform environment characteristics.
/// </summary>
public interface IEnvironmentService
{
/// <summary>
/// Gets a bool representing whether or not is the app is running on a simulator or device.
/// </summary>
/// <value>True if the device is real, false if a simulator/emulator.</value>
bool IsRealDevice { get; }
}
}
namespace inutralia.Abstractions
{
/// <summary>
/// Entidad que tiene un Id de tipo entero
/// </summary>
public interface IIdentifiableEntity
{
/// <summary>
/// Identificador de la entidad
/// </summary>
int Id { get; set; }
}
/// <summary>
/// Entidad que tiene un Id de tipo entero
/// </summary>
public interface IIdentifiableEntity
{
/// <summary>
/// Identificador de la entidad
/// </summary>
int Id { get; set; }
}
}
......@@ -12,28 +12,28 @@ namespace inutralia
{
//https://developer.android.com/guide/topics/manifest/activity-element.html
[Activity(
Label = "iNutralia",
Icon = "@drawable/icon",
Theme = "@style/Theme.Splash",
MainLauncher = true,
LaunchMode = LaunchMode.SingleTask,
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize,
Label = "iNutralia",
Icon = "@drawable/icon",
Theme = "@style/Theme.Splash",
MainLauncher = true,
LaunchMode = LaunchMode.SingleTask,
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize,
ScreenOrientation = ScreenOrientation.Portrait
)
]
public class MainActivity : FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
// Changing to App's theme since we are OnCreate and we are ready to
// "hide" the splash
base.Window.RequestFeature(WindowFeatures.ActionBar);
base.SetTheme(Resource.Style.AppTheme);
]
public class MainActivity : FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
// Changing to App's theme since we are OnCreate and we are ready to
// "hide" the splash
base.Window.RequestFeature(WindowFeatures.ActionBar);
base.SetTheme(Resource.Style.AppTheme);
FormsAppCompatActivity.ToolbarResource = Resource.Layout.Toolbar;
FormsAppCompatActivity.TabLayoutResource = Resource.Layout.Tabs;
FormsAppCompatActivity.ToolbarResource = Resource.Layout.Toolbar;
FormsAppCompatActivity.TabLayoutResource = Resource.Layout.Tabs;
base.OnCreate(bundle);
base.OnCreate(bundle);
Window.AddFlags(WindowManagerFlags.Fullscreen);
......@@ -41,30 +41,33 @@ namespace inutralia
FFImageLoading.Forms.Platform.CachedImageRenderer.Init(true);
Forms.Init(this, bundle);
//Initializing GrialKit
GrialKit.Init(this, "inutralia.GrialLicense");
FormsHelper.ForceLoadingAssemblyContainingType(typeof(UXDivers.Effects.Effects));
FormsHelper.ForceLoadingAssemblyContainingType(typeof(UXDivers.Effects.Effects));
LoadApplication(new App());}
LoadApplication(new App());
}
public override void OnConfigurationChanged(Android.Content.Res.Configuration newConfig)
{
base.OnConfigurationChanged(newConfig);
public override void OnConfigurationChanged(Android.Content.Res.Configuration newConfig)
{
base.OnConfigurationChanged(newConfig);
DeviceOrientationLocator.NotifyOrientationChanged();
}
DeviceOrientationLocator.NotifyOrientationChanged();
}
public override void OnBackPressed ()
public override void OnBackPressed()
{
var md = Xamarin.Forms.Application.Current.MainPage as MasterDetailPage;
if (md != null && !md.IsPresented &&
(
!(md.Detail is NavigationPage) || (((NavigationPage) md.Detail).Navigation.NavigationStack.Count == 1 && ((NavigationPage) md.Detail).Navigation.ModalStack.Count == 0)
!(md.Detail is NavigationPage) || (((NavigationPage)md.Detail).Navigation.NavigationStack.Count == 1 && ((NavigationPage)md.Detail).Navigation.ModalStack.Count == 0)
))
MoveTaskToBack (true);
MoveTaskToBack(true);
else
base.OnBackPressed ();
base.OnBackPressed();
}
}
}
......
......@@ -4,61 +4,68 @@ using Xamarin.Forms;
namespace inutralia
{
public class CustomFontLabelRenderer : ArtinaCustomFontLabelRenderer
{
private static readonly string[] CustomFontFamily = new []
public class CustomFontLabelRenderer : ArtinaCustomFontLabelRenderer
{
private static readonly string[] CustomFontFamily = new[]
{
"grialshapes",
"FontAwesome",
"Ionicons"
};
private static readonly Tuple<FontAttributes, string>[][] CustomFontFamilyData = new [] {
new [] {
new Tuple<FontAttributes, string>(FontAttributes.None, "grialshapes.ttf"),
new Tuple<FontAttributes, string>(FontAttributes.Bold, "grialshapes.ttf"),
new Tuple<FontAttributes, string>(FontAttributes.Italic, "grialshapes.ttf")
},
private static readonly Tuple<FontAttributes, string>[][] CustomFontFamilyData = new[] {
new []
{
new Tuple<FontAttributes, string>(FontAttributes.None, "grialshapes.ttf"),
new Tuple<FontAttributes, string>(FontAttributes.Bold, "grialshapes.ttf"),
new Tuple<FontAttributes, string>(FontAttributes.Italic, "grialshapes.ttf")
},
//*
new [] {
new Tuple<FontAttributes, string>(FontAttributes.None, "fontawesome-webfont.ttf"),
new Tuple<FontAttributes, string>(FontAttributes.Bold, "fontawesome-webfont.ttf"),
new Tuple<FontAttributes, string>(FontAttributes.Italic, "fontawesome-webfont.ttf")
},
new []
{
new Tuple<FontAttributes, string>(FontAttributes.None, "fontawesome-webfont.ttf"),
new Tuple<FontAttributes, string>(FontAttributes.Bold, "fontawesome-webfont.ttf"),
new Tuple<FontAttributes, string>(FontAttributes.Italic, "fontawesome-webfont.ttf")
},
//*/
//*
new [] {
new Tuple<FontAttributes, string>(FontAttributes.None, "ionicons.ttf"),
new Tuple<FontAttributes, string>(FontAttributes.Bold, "ionicons.ttf"),
new Tuple<FontAttributes, string>(FontAttributes.Italic, "ionicons.ttf")
}
new []
{
new Tuple<FontAttributes, string>(FontAttributes.None, "ionicons.ttf"),
new Tuple<FontAttributes, string>(FontAttributes.Bold, "ionicons.ttf"),
new Tuple<FontAttributes, string>(FontAttributes.Italic, "ionicons.ttf")
}
//*/
};
protected override bool CheckIfCustomFont (string fontFamily, FontAttributes attributes, out string fontFileName)
{
for (int i = 0; i < CustomFontFamily.Length; i++) {
if (string.Equals(fontFamily, CustomFontFamily[i], StringComparison.InvariantCulture)){
var fontFamilyData = CustomFontFamilyData[i];
for (int j = 0; j < fontFamilyData.Length; j++) {
var data = fontFamilyData[j];
if (data.Item1 == attributes){
fontFileName = data.Item2;
protected override bool CheckIfCustomFont(string fontFamily, FontAttributes attributes, out string fontFileName)
{
for (int i = 0; i < CustomFontFamily.Length; i++)
{
if (string.Equals(fontFamily, CustomFontFamily[i], StringComparison.InvariantCulture))
{
var fontFamilyData = CustomFontFamilyData[i];
for (int j = 0; j < fontFamilyData.Length; j++)
{
var data = fontFamilyData[j];
if (data.Item1 == attributes)
{
fontFileName = data.Item2;
return true;
}
}
return true;
}
}
break;
}
}
break;
}
}
fontFileName = null;
return false;
}
}
fontFileName = null;
return false;
}
}
}
<?xml version="1.0" encoding="UTF-8" ?>
<resources>
<bool name="largeheap">true</bool>
<bool name="largeheap">true</bool>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<color name="primary">@color/AccentColor</color>
<color name="primary_dark">@color/AccentColor</color>
<color name="actionbar_tab_indicator">@color/AccentColor</color>
<color name="primary">@color/AccentColor</color>
<color name="primary_dark">@color/AccentColor</color>
<color name="actionbar_tab_indicator">@color/AccentColor</color>
<!-- Theme -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Theme -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Set AppCompat’s color theming attrs -->
<!-- Set AppCompat’s color theming attrs -->
<!-- colorPrimary is used for the default action bar background -->
<item name="colorPrimary">@color/AccentColor</item>
<!-- colorPrimary is used for the default action bar background -->
<item name="colorPrimary">@color/AccentColor</item>
<!-- colorPrimaryDark is used for the status bar -->
<item name="colorPrimaryDark">#000000</item>
<!-- colorPrimaryDark is used for the status bar -->
<item name="colorPrimaryDark">#000000</item>
<!-- colorAccent is used as the default value for colorControlActivated,
<!-- colorAccent is used as the default value for colorControlActivated,
which is used to tint widgets -->
<item name="colorAccent">@color/AccentColor</item>
<item name="colorAccent">@color/AccentColor</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<!-- Used on ListView selected items -->
<item name="android:color">@color/AccentColor</item>
<item name="android:colorPressedHighlight">@color/AccentColor</item>
<item name="android:colorLongPressedHighlight">@color/AccentColor</item>
<item name="android:colorFocusedHighlight">@color/AccentColor</item>
<item name="android:colorActivatedHighlight">@color/AccentColor</item>
<item name="android:activatedBackgroundIndicator">@color/AccentColor</item>
<!-- Used on ListView selected items -->
<item name="android:color">@color/AccentColor</item>
<item name="android:colorPressedHighlight">@color/AccentColor</item>
<item name="android:colorLongPressedHighlight">@color/AccentColor</item>
<item name="android:colorFocusedHighlight">@color/AccentColor</item>
<item name="android:colorActivatedHighlight">@color/AccentColor</item>
<item name="android:activatedBackgroundIndicator">@color/AccentColor</item>
<!-- Main theme colors -->
<!-- your app branding color for the app bar -->
<item name="android:colorPrimary">@color/primary</item>
<!-- Main theme colors -->
<!-- your app branding color for the app bar -->
<item name="android:colorPrimary">@color/primary</item>
<!-- darker variant for the status bar and contextual app bars
<!-- darker variant for the status bar and contextual app bars
<item name="android:colorPrimaryDark">@color/primary_dark</item>-->
<!-- theme UI controls like checkboxes and text fields -->
<item name="android:colorAccent">@color/AccentColor</item>
<!-- TimePicker dialog-->
<item name="android:dialogTheme">@style/AppTheme.Dialog</item>
<item name="android:timePickerDialogTheme">@style/AppTheme.Dialog</item>
<item name="android:datePickerDialogTheme">@style/AppTheme.Dialog</item>
<item name="alertDialogTheme">@style/AppTheme.AlertDialog</item>
<item name="drawerArrowStyle">@style/AppTheme.DrawerArrowStyle</item>
<item name="android:windowContentTransitions">true</item>
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:windowAllowReturnTransitionOverlap">true</item>
<item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
<item name="android:windowSharedElementExitTransition">@android:transition/move</item>
</style>
<!-- Adding animation to hamburguer icon, and overriding color to fix weird color change bug on app compat -->
<style name="AppTheme.DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
<item name="spinBars">true</item>
<item name="color">#FFFFFF</item>
</style>
<!-- DatePicker style -->
<style name="AppTheme.Dialog" parent="android:Theme.Material.Light.Dialog.Alert">
<item name="android:colorAccent">@color/AccentColor</item>
<item name="android:textColorPrimary">@color/AccentColor</item>
</style>
<style name="AppTheme.DialogTitleTextStyle">
<item name="android:textColor">@color/AccentColor</item>
<item name="android:textAppearance">@style/TextAppearance.AppCompat.Title</item>
</style>
<style name="AppTheme.AlertDialog" parent="android:Theme.Material.Light.Dialog.Alert">
<item name="android:colorAccent">@color/AccentColor</item>
<item name="android:windowTitleStyle">@style/AppTheme.DialogTitleTextStyle</item>
<item name="android:windowNoTitle">true</item>
</style>
<!-- theme UI controls like checkboxes and text fields -->
<item name="android:colorAccent">@color/AccentColor</item>
<!-- TimePicker dialog-->
<item name="android:dialogTheme">@style/AppTheme.Dialog</item>
<item name="android:timePickerDialogTheme">@style/AppTheme.Dialog</item>
<item name="android:datePickerDialogTheme">@style/AppTheme.Dialog</item>
<item name="alertDialogTheme">@style/AppTheme.AlertDialog</item>
<item name="drawerArrowStyle">@style/AppTheme.DrawerArrowStyle</item>
<item name="android:windowContentTransitions">true</item>
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:windowAllowReturnTransitionOverlap">true</item>
<item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
<item name="android:windowSharedElementExitTransition">@android:transition/move</item>
</style>
<!-- Adding animation to hamburguer icon, and overriding color to fix weird color change bug on app compat -->
<style name="AppTheme.DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
<item name="spinBars">true</item>
<item name="color">#FFFFFF</item>
</style>
<!-- DatePicker style -->
<style name="AppTheme.Dialog" parent="android:Theme.Material.Light.Dialog.Alert">
<item name="android:colorAccent">@color/AccentColor</item>
<item name="android:textColorPrimary">@color/AccentColor</item>
</style>
<style name="AppTheme.DialogTitleTextStyle">
<item name="android:textColor">@color/AccentColor</item>
<item name="android:textAppearance">@style/TextAppearance.AppCompat.Title</item>
</style>
<style name="AppTheme.AlertDialog" parent="android:Theme.Material.Light.Dialog.Alert">
<item name="android:colorAccent">@color/AccentColor</item>
<item name="android:windowTitleStyle">@style/AppTheme.DialogTitleTextStyle</item>
<item name="android:windowNoTitle">true</item>
</style>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="AccentColor">#FFA2C300</color>
<color name="ComplementColor">#FFD480D6</color>
<color name="BaseTextColor">#FF666666</color>
<color name="AccentColor">#FFA2C300</color>
<color name="ComplementColor">#FFD480D6</color>
<color name="BaseTextColor">#FF666666</color>
</resources>
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<!-- Splash styles -->
<style name="Theme.Splash" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">@drawable/splash_drawable</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsTranslucent">false</item>
<item name="android:windowIsFloating">false</item>
<item name="android:backgroundDimEnabled">true</item>
</style>
<!-- Splash styles -->
<style name="Theme.Splash" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">@drawable/splash_drawable</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsTranslucent">false</item>
<item name="android:windowIsFloating">false</item>
<item name="android:backgroundDimEnabled">true</item>
</style>
<!-- Theme -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Theme -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Set AppCompat’s color theming attrs -->
<!-- Set AppCompat’s color theming attrs -->
<!-- colorPrimary is used for the default action bar background -->
<item name="colorPrimary">@color/AccentColor</item>
<!-- colorPrimary is used for the default action bar background -->
<item name="colorPrimary">@color/AccentColor</item>
<!-- colorPrimaryDark is used for the status bar
<!-- colorPrimaryDark is used for the status bar
<item name="colorPrimaryDark">@color/AccentColor</item>-->
<!-- colorAccent is used as the default value for colorControlActivated,
<!-- colorAccent is used as the default value for colorControlActivated,
which is used to tint widgets -->
<item name="colorAccent">@color/AccentColor</item>
<item name="colorAccent">@color/AccentColor</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<!-- Used on ListView selected items -->
<item name="android:color">@color/AccentColor</item>
<item name="android:colorPressedHighlight">@color/AccentColor</item>
<item name="android:colorLongPressedHighlight">@color/AccentColor</item>
<item name="android:colorFocusedHighlight">@color/AccentColor</item>
<item name="android:colorActivatedHighlight">@color/AccentColor</item>
<item name="android:activatedBackgroundIndicator">@color/AccentColor</item>
<!-- Used on ListView selected items -->
<item name="android:color">@color/AccentColor</item>
<item name="android:colorPressedHighlight">@color/AccentColor</item>
<item name="android:colorLongPressedHighlight">@color/AccentColor</item>
<item name="android:colorFocusedHighlight">@color/AccentColor</item>
<item name="android:colorActivatedHighlight">@color/AccentColor</item>
<item name="android:activatedBackgroundIndicator">@color/AccentColor</item>
<!-- Main theme colors -->
<!-- your app branding color for the app bar -->
<item name="android:colorPrimary">@color/AccentColor</item>
<!-- Main theme colors -->
<!-- your app branding color for the app bar -->
<item name="android:colorPrimary">@color/AccentColor</item>
<!-- darker variant for the status bar and contextual app bars
<!-- darker variant for the status bar and contextual app bars
<item name="android:colorPrimaryDark">@color/primary_dark</item>-->
<!-- theme UI controls like checkboxes and text fields -->
<item name="android:colorAccent">@color/AccentColor</item>
<!-- Dialog attributes -->
<item name="dialogTheme">@style/AppTheme.Dialog</item>
<!-- AlertDialog attributes -->
<item name="alertDialogTheme">@style/AppTheme.Dialog</item>
<item name="drawerArrowStyle">@style/AppTheme.DrawerArrowStyle</item>
<item name="android:showDividers">none</item>
<item name="android:divider">@null</item>
<item name="android:datePickerStyle">@style/Widget.AppTheme.Picker</item>
</style>
<!-- Adding animation to hamburguer icon, and overriding color to fix weird color change bug on app compat -->
<style name="AppTheme.DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
<item name="spinBars">true</item>
<item name="color">#FFFFFF</item>
</style>
<style name="AppTheme.Dialog" parent="@style/Theme.AppCompat.Light.Dialog">
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
<item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
<item name="android:textColorAlertDialogListItem">@color/AccentColor</item>
<item name="android:textColor">@color/AccentColor</item>
<item name="colorAccent">@color/AccentColor</item>
<item name="android:borderlessButtonStyle">@style/Widget.AppTheme.Button.Borderless</item>
</style>
<style name="Widget.AppTheme.Button.Borderless" parent="@style/Widget.AppCompat.Button.Borderless">
<item name="android:textColor">#FF00FF</item>
<item name="android:textAppearance">@style/TextAppearance.AppTheme.DialogButton</item>
</style>
<style name="Widget.AppTheme.TabLayout" parent="@style/Widget.Design.TabLayout">
<item name="tabSelectedTextColor">@color/AccentColor</item>
<item name="tabTextColor">@color/BaseTextColor</item>
</style>
<style name="Widget.AppTheme.Picker" parent="@style/Theme.AppCompat.Light.Dialog">
<item name="android:colorPrimary">@color/AccentColor</item>
<item name="android:colorPrimaryDark">@color/AccentColor</item>
<item name="android:colorAccent">@color/AccentColor</item>
<item name="android:textColor">@color/AccentColor</item>
</style>
<style name="TextAppearance.AppTheme.DialogButton" parent="@style/TextAppearance.AppCompat.Title">
</style>
<!-- theme UI controls like checkboxes and text fields -->
<item name="android:colorAccent">@color/AccentColor</item>
<!-- Dialog attributes -->
<item name="dialogTheme">@style/AppTheme.Dialog</item>
<!-- AlertDialog attributes -->
<item name="alertDialogTheme">@style/AppTheme.Dialog</item>
<item name="drawerArrowStyle">@style/AppTheme.DrawerArrowStyle</item>
<item name="android:showDividers">none</item>
<item name="android:divider">@null</item>
<item name="android:datePickerStyle">@style/Widget.AppTheme.Picker</item>
</style>
<!-- Adding animation to hamburguer icon, and overriding color to fix weird color change bug on app compat -->
<style name="AppTheme.DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
<item name="spinBars">true</item>
<item name="color">#FFFFFF</item>
</style>
<style name="AppTheme.Dialog" parent="@style/Theme.AppCompat.Light.Dialog">
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
<item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
<item name="android:textColorAlertDialogListItem">@color/AccentColor</item>
<item name="android:textColor">@color/AccentColor</item>
<item name="colorAccent">@color/AccentColor</item>
<item name="android:borderlessButtonStyle">@style/Widget.AppTheme.Button.Borderless</item>
</style>
<style name="Widget.AppTheme.Button.Borderless" parent="@style/Widget.AppCompat.Button.Borderless">
<item name="android:textColor">#FF00FF</item>
<item name="android:textAppearance">@style/TextAppearance.AppTheme.DialogButton</item>
</style>
<style name="Widget.AppTheme.TabLayout" parent="@style/Widget.Design.TabLayout">
<item name="tabSelectedTextColor">@color/AccentColor</item>
<item name="tabTextColor">@color/BaseTextColor</item>
</style>
<style name="Widget.AppTheme.Picker" parent="@style/Theme.AppCompat.Light.Dialog">
<item name="android:colorPrimary">@color/AccentColor</item>
<item name="android:colorPrimaryDark">@color/AccentColor</item>
<item name="android:colorAccent">@color/AccentColor</item>
<item name="android:textColor">@color/AccentColor</item>
</style>
<style name="TextAppearance.AppTheme.DialogButton" parent="@style/TextAppearance.AppCompat.Title">
</style>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.5.0.0" newVersion="1.5.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.5.0.0" newVersion="1.5.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
\ No newline at end of file
using Newtonsoft.Json;
using System;
using System.ComponentModel;
using System.Globalization;
namespace inutralia.Models
{
[JsonObject(MemberSerialization.OptIn)]
[DataPath("article")]
public class Article : ObservableEntityData
{
[JsonProperty("title", Required = Required.Always)]
public string Title { get; set; }
[JsonObject(MemberSerialization.OptIn)]
[DataPath("article")]
public class Article : ObservableEntityData
{
[JsonProperty("title", Required = Required.Always)]
public string Title { get; set; }
[JsonProperty("excerpt")]
public string Excerpt { get; set; }
[JsonProperty("excerpt")]
public string Excerpt { get; set; }
[JsonProperty("body")]
public string Body { get; set; }
[JsonProperty("body")]
public string Body { get; set; }
[JsonProperty("photo")]
public string Photo { get; set; }
[JsonProperty("photo")]
public string Photo { get; set; }
[JsonProperty("published")]
public string Date { get; set; }
public string ExcerptCompress => Excerpt == null ? "..." : Excerpt.Substring(0, Math.Min(80, Excerpt.Length)).Length<80 ? Excerpt : Excerpt.Substring(0, Excerpt.Substring(0, 80).LastIndexOf(" ")) + ((Excerpt.Length>80) ? "..." : "" );
public string ExcerptCompress => Excerpt == null ? "..." : Excerpt.Substring(0, Math.Min(80, Excerpt.Length)).Length < 80 ? Excerpt : Excerpt.Substring(0, Excerpt.Substring(0, 80).LastIndexOf(" ")) + ((Excerpt.Length > 80) ? "..." : "");
}
}
......@@ -20,5 +20,4 @@ namespace inutralia
return objectType == typeof(bool);
}
}
}
......@@ -7,10 +7,12 @@ namespace inutralia.Models
/// este atributo, se utilizará el nombre de la clase en minúsculas con una 's' al
/// final
/// </summary>
///
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class DataPathAttribute : Attribute
{
public DataPathAttribute ( string path)
public DataPathAttribute(string path)
{
DataPath = path;
}
......

using Newtonsoft.Json;
using Newtonsoft.Json;
using System.Collections.Generic;
namespace inutralia.Models
{
[JsonObject(MemberSerialization.OptIn)]
public class Day
{
[JsonProperty("ds", Required = Required.Always)]
public string Ds { get; set; }
[JsonObject(MemberSerialization.OptIn)]
public class Day
{
[JsonProperty("ds", Required = Required.Always)]
public string Ds { get; set; }
[JsonProperty("lunchFirst", Required = Required.Always)]
public IList<Recipe> LunchFirst { get; set; }
[JsonProperty("lunchSecond", Required = Required.Always)]
public IList<Recipe> LunchSecond { get; set; }
[JsonProperty("lunchFirst", Required = Required.Always)]
public IList<Recipe> LunchFirst { get; set; }
[JsonProperty("dinnerFirst", Required = Required.Always)]
public IList<Recipe> DinnerFirst { get; set; }
[JsonProperty("lunchSecond", Required = Required.Always)]
public IList<Recipe> LunchSecond { get; set; }
[JsonProperty("dinnerSecond", Required = Required.Always)]
public IList<Recipe> DinnerSecond { get; set; }
[JsonProperty("dinnerFirst", Required = Required.Always)]
public IList<Recipe> DinnerFirst { get; set; }
public Day()
{
[JsonProperty("dinnerSecond", Required = Required.Always)]
public IList<Recipe> DinnerSecond { get; set; }
}
}
public Day() { }
}
}
using Newtonsoft.Json;
using System.ComponentModel;
using System;
namespace inutralia.Models
{
[JsonObject(MemberSerialization.OptIn)]
[DataPath("generic")]
public class Generic : MenuBase
{
[JsonProperty("ds", Required = Required.Always)]
public string Ds
{ get; set; }
[JsonObject(MemberSerialization.OptIn)]
[DataPath("generic")]
public class Generic : MenuBase
{
[JsonProperty("ds", Required = Required.Always)]
public string Ds { get; set; }
public override string Title
{
get
{
return Ds;
}
get { return Ds; }
}
}
}

using Newtonsoft.Json;
using System.ComponentModel;
using System.Linq;
using System.Runtime.Serialization;
using Newtonsoft.Json;
namespace inutralia.Models
{
[JsonObject(MemberSerialization.OptIn)]
[DataPath("recipe")]
public class Ingredient : ObservableEntityData
{
[JsonProperty("name", Required = Required.Always)]
public string Name { get; set; }
[JsonObject(MemberSerialization.OptIn)]
[DataPath("recipe")]
public class Ingredient : ObservableEntityData
{
[JsonProperty("name", Required = Required.Always)]
public string Name { get; set; }
[JsonProperty("cuantity")]
public string Cuantity { get; set; }
[JsonProperty("cuantity")]
public string Cuantity { get; set; }
[JsonProperty("order")]
public int Order { get; set; }
[JsonProperty("order")]
public int Order { get; set; }
public Ingredient() { }
}
}
}
using Newtonsoft.Json;
using System.ComponentModel;
using System;
namespace inutralia.Models
{
/// <summary>
/// Representa el menú personal guardado localmente
/// </summary>
[JsonObject (MemberSerialization.OptIn)]
[DataPath ("LocalMenu")]
/// </summary>
[JsonObject(MemberSerialization.OptIn)]
[DataPath("LocalMenu")]
public class LocalMenu : Menu
{
private static JsonSerializerSettings _jsonSettings = new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace, NullValueHandling = NullValueHandling.Ignore};
private static JsonSerializerSettings _jsonSettings = new JsonSerializerSettings
{
ObjectCreationHandling = ObjectCreationHandling.Replace,
NullValueHandling = NullValueHandling.Ignore
};
/// <summary>
/// Indice del plato seleccionado para un día
/// </summary>
public class MealSelections
{
[JsonProperty ("lf_idx", DefaultValueHandling = DefaultValueHandling.Populate)]
[JsonProperty("lf_idx", DefaultValueHandling = DefaultValueHandling.Populate)]
[DefaultValue(-1)]
public int LunchFirstIndex = -1;
[JsonProperty ("ls_idx", DefaultValueHandling = DefaultValueHandling.Populate)]
[DefaultValue (-1)]
[JsonProperty("ls_idx", DefaultValueHandling = DefaultValueHandling.Populate)]
[DefaultValue(-1)]
public int LunchSecondIndex = -1;
[JsonProperty ("df_idx", DefaultValueHandling = DefaultValueHandling.Populate)]
[DefaultValue (-1)]
[JsonProperty("df_idx", DefaultValueHandling = DefaultValueHandling.Populate)]
[DefaultValue(-1)]
public int DinnerFirstIndex = -1;
[JsonProperty ("ds_idx", DefaultValueHandling = DefaultValueHandling.Populate)]
[DefaultValue (-1)]
[JsonProperty("ds_idx", DefaultValueHandling = DefaultValueHandling.Populate)]
[DefaultValue(-1)]
public int DinnerSecondIndex = -1;
}
......@@ -40,7 +42,7 @@ namespace inutralia.Models
/// Platos seleccionados para cada uno de los días
/// </summary>
[JsonProperty("day_selections")]
public MealSelections [] DaySelections;
public MealSelections[] DaySelections;
/// <summary>
/// Identificador del último menú semanal recibido del servidor
......@@ -52,19 +54,18 @@ namespace inutralia.Models
/// Copia los datos del menú recibido del servidor
/// </summary>
/// <param name="menu">El recibido del servidor</param>
public void AssignFromMenu ( Menu menu)
public void AssignFromMenu(Menu menu)
{
// Usar el serializador Json para copiar los datos del menú
JsonConvert.PopulateObject (JsonConvert.SerializeObject (menu), this, _jsonSettings);
JsonConvert.PopulateObject(JsonConvert.SerializeObject(menu), this, _jsonSettings);
// Borrar la selección de los platos de cada día
DaySelections = new MealSelections [7];
DaySelections = new MealSelections[7];
for (int i = 0; i < 7; i++)
DaySelections[i] = new MealSelections ();
DaySelections[i] = new MealSelections();
// Asignar último menú recibido
LastReceivedMenuId = menu.Id;
}
}
}
using Newtonsoft.Json;
using System.ComponentModel;
using System;
namespace inutralia.Models
{
[JsonObject(MemberSerialization.OptIn)]
[DataPath("menu")]
public class Menu : MenuBase
{
[JsonProperty("recomendation", DefaultValueHandling = DefaultValueHandling.Populate)]
[DefaultValue("")]
public string Recomendation
{ get; set; }
[JsonObject(MemberSerialization.OptIn)]
[DataPath("menu")]
[JsonProperty("intro", DefaultValueHandling = DefaultValueHandling.Populate)]
[DefaultValue("")]
public string Intro
{ get; set; }
public class Menu : MenuBase
{
[JsonProperty("recomendation", DefaultValueHandling = DefaultValueHandling.Populate)]
[DefaultValue("")]
public string Recomendation { get; set; }
[JsonProperty("intro", DefaultValueHandling = DefaultValueHandling.Populate)]
[DefaultValue("")]
public string Intro { get; set; }
public override string Title
{
......@@ -26,8 +24,6 @@ namespace inutralia.Models
}
}
public Menu()
{
}
}
public Menu() { }
}
}
......@@ -2,60 +2,50 @@
using System.Collections.Generic;
using System.ComponentModel;
namespace inutralia.Models
{
public abstract class MenuBase : ObservableEntityData
public abstract class MenuBase : ObservableEntityData
{
public abstract string Title { get; }
[JsonProperty("days")]
public IList<Day> Days
{ get; set; }
[JsonProperty("recBreakfastBase")]
[DefaultValue("")]
public string RecBreakfastBase
{ get; set; }
[JsonProperty("recBreakfastExt")]
[DefaultValue("")]
public string RecBreakfastExt
{ get; set; }
[JsonProperty("recMorningBase")]
[DefaultValue("")]
public string RecMorningBase
{ get; set; }
[JsonProperty("recMorningExt")]
[DefaultValue("")]
public string RecMorningExt
{ get; set; }
[JsonProperty("recAfternoonBase")]
[DefaultValue("")]
public string RecAfternoonBase
{ get; set; }
[JsonProperty("recAfternoonExt")]
[DefaultValue("")]
public string RecAfternoonExt
{ get; set; }
[JsonProperty("recGeneralBase")]
[DefaultValue("")]
public string RecGeneralBase
{ get; set; }
[JsonProperty("recGeneralExt")]
[DefaultValue("")]
public string RecGeneralExt
{ get; set; }
public string resume => "<br><div style='background-color:#62b9ae; overflow: auto; width:100%; text-align:center'><h3 style='color:#FFFFFF'> DESAYUNO </h3></div><br>" + RecBreakfastBase + "<br>" + RecBreakfastExt +
"<br><div style='background-color:#62b9ae; overflow: auto; width:100%; text-align:center'><h3 style='color:#FFFFFF'> MEDIA MAÑANA </h3></div><br>" + RecMorningBase + "<br>" + RecMorningExt +
[JsonProperty("days")]
public IList<Day> Days { get; set; }
[JsonProperty("recBreakfastBase")]
[DefaultValue("")]
public string RecBreakfastBase { get; set; }
[JsonProperty("recBreakfastExt")]
[DefaultValue("")]
public string RecBreakfastExt { get; set; }
[JsonProperty("recMorningBase")]
[DefaultValue("")]
public string RecMorningBase { get; set; }
[JsonProperty("recMorningExt")]
[DefaultValue("")]
public string RecMorningExt { get; set; }
[JsonProperty("recAfternoonBase")]
[DefaultValue("")]
public string RecAfternoonBase { get; set; }
[JsonProperty("recAfternoonExt")]
[DefaultValue("")]
public string RecAfternoonExt { get; set; }
[JsonProperty("recGeneralBase")]
[DefaultValue("")]
public string RecGeneralBase { get; set; }
[JsonProperty("recGeneralExt")]
[DefaultValue("")]
public string RecGeneralExt { get; set; }
public string resume => "<br><div style='background-color:#62b9ae; overflow: auto; width:100%; text-align:center'><h3 style='color:#FFFFFF'> DESAYUNO </h3></div><br>" + RecBreakfastBase + "<br>" + RecBreakfastExt +
"<br><div style='background-color:#62b9ae; overflow: auto; width:100%; text-align:center'><h3 style='color:#FFFFFF'> MEDIA MAÑANA </h3></div><br>" + RecMorningBase + "<br>" + RecMorningExt +
"<br><div style='background-color:#62b9ae; overflow: auto; width:100%; text-align:center'><h3 style='color:#FFFFFF'> MERIENDA </h3></div><br>" + RecAfternoonBase + "<br>" + RecAfternoonExt +
"<br><div style='background-color:#62b9ae; overflow: auto; width:100%; text-align:center'><h3 style='color:#FFFFFF'> CONSEJOS GENERALES </h3></div><br>" + RecGeneralBase + "<br>" + RecGeneralExt ;
"<br><div style='background-color:#62b9ae; overflow: auto; width:100%; text-align:center'><h3 style='color:#FFFFFF'> CONSEJOS GENERALES </h3></div><br>" + RecGeneralBase + "<br>" + RecGeneralExt;
}
}
\ No newline at end of file
......@@ -9,14 +9,14 @@ namespace inutralia.Models
/// </summary>
public class ObservableEntityData : ObservableObject, IIdentifiableEntity
{
public ObservableEntityData ()
public ObservableEntityData()
{
// Los identificadores negativos indican que la entidad es nueva y no
// existe por tanto en la base de datos
Id = -1;
}
[JsonProperty ("id", Required = Required.Always)]
[JsonProperty("id", Required = Required.Always)]
public int Id { get; set; }
}
}
using Newtonsoft.Json;
using System.ComponentModel;
using System.Linq;
using System.Runtime.Serialization;
namespace inutralia.Models
{
[JsonObject(MemberSerialization.OptIn)]
[DataPath("profile")]
public class Profile : ObservableEntityData
{
[JsonProperty("code")]
[DefaultValue("")]
public string Code { get; set; }
[JsonProperty("age")]
[DefaultValue(0)]
public int Age { get; set; }
[JsonProperty("gender")]
[DefaultValue('M')]
public char Gender { get; set; }
[JsonProperty("height")]
[DefaultValue(0)]
public int Height { get; set; }
[JsonProperty("weight")]
[DefaultValue(0)]
//public int _Weight;
//public int Weight { get { return _Weight;} set { SetProperty(ref _Weight,value);} }
public int Weight { get; set; }
[JsonProperty("physical")]
[DefaultValue(0)]
public int Physical { get; set; }
[JsonProperty("menopause")]
[JsonObject(MemberSerialization.OptIn)]
[DataPath("profile")]
public class Profile : ObservableEntityData
{
[JsonProperty("code")]
[DefaultValue("")]
public string Code { get; set; }
[JsonProperty("age")]
[DefaultValue(0)]
public int Age { get; set; }
[JsonProperty("gender")]
[DefaultValue('M')]
public char Gender { get; set; }
[JsonProperty("height")]
[DefaultValue(0)]
public int Height { get; set; }
[JsonProperty("weight")]
[DefaultValue(0)]
public int Weight { get; set; }
[JsonProperty("physical")]
[DefaultValue(0)]
public int Physical { get; set; }
[JsonProperty("menopause")]
[JsonConverter(typeof(BoolConverter))]
[DefaultValue("0")]
public bool Menopause { get; set; }
public bool Menopause { get; set; }
[JsonProperty("pregnancy")]
[JsonConverter(typeof(BoolConverter))]
[DefaultValue("0")]
......@@ -48,65 +44,62 @@ namespace inutralia.Models
[JsonProperty("lactation")]
[JsonConverter(typeof(BoolConverter))]
[DefaultValue("0")]
public bool Lactation { get; set; }
public bool Lactation { get; set; }
[JsonProperty("celiac")]
[JsonConverter(typeof(BoolConverter))]
[DefaultValue("0")]
public bool Celiac { get; set; }
public bool Celiac { get; set; }
[JsonProperty("lactose")]
[JsonConverter(typeof(BoolConverter))]
[DefaultValue("0")]
public bool Lactose { get; set; }
public bool Lactose { get; set; }
[JsonProperty("diabetes")]
[JsonConverter(typeof(BoolConverter))]
[DefaultValue("0")]
public bool Diabetes { get; set; }
public bool Diabetes { get; set; }
[JsonProperty("cholesterol")]
[JsonConverter(typeof(BoolConverter))]
[DefaultValue("0")]
public bool Cholesterol { get; set; }
public bool Cholesterol { get; set; }
[JsonProperty("hypertension")]
[JsonConverter(typeof(BoolConverter))]
[DefaultValue("0")]
public bool Hypertension { get; set; }
public bool Hypertension { get; set; }
[JsonProperty("triglycerides")]
[JsonConverter(typeof(BoolConverter))]
[DefaultValue("0")]
public bool Triglycerides { get; set; }
public bool Triglycerides { get; set; }
[JsonProperty("cv")]
[JsonConverter(typeof(BoolConverter))]
[DefaultValue("0")]
public bool Cv { get; set; }
public bool Cv { get; set; }
[JsonProperty("al_fish")]
[JsonConverter(typeof(BoolConverter))]
[DefaultValue("0")]
public bool Al_fish { get; set; }
public bool Al_fish { get; set; }
[JsonProperty("al_egg")]
[JsonConverter(typeof(BoolConverter))]
[DefaultValue("0")]
public bool Al_egg { get; set; }
public bool Al_egg { get; set; }
[JsonProperty("al_nuts")]
[JsonConverter(typeof(BoolConverter))]
[DefaultValue("0")]
public bool Al_nuts { get; set; }
public bool Al_nuts { get; set; }
[JsonProperty("preference")]
[DefaultValue(0)]
public int Preference { get; set; }
public int Preference { get; set; }
public Profile()
{
}
}
public Profile() { }
}
}

using Newtonsoft.Json;
using Newtonsoft.Json;
using System.Collections.Generic;
namespace inutralia.Models
{
[JsonObject(MemberSerialization.OptIn)]
[DataPath("recipe")]
[JsonObject(MemberSerialization.OptIn)]
[DataPath("recipe")]
public class Recipe : ObservableEntityData
{
public class Recipe : ObservableEntityData
{
[JsonProperty("name", Required = Required.Always)]
public string Name { get; set; }
[JsonProperty("shortName")]
public string ShortName { get; set; }
public string ShortName { get; set; }
[JsonProperty("excerpt")]
public string Excerpt { get; set; }
[JsonProperty("excerpt")]
public string Excerpt { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("image")]
public string Image { get; set; }
[JsonProperty("image")]
public string Image { get; set; }
[JsonProperty("time")]
public int Time { get; set; }
[JsonProperty("time")]
public int Time { get; set; }
[JsonProperty("difficulty")]
public string Difficulty { get; set; }
[JsonProperty("difficulty")]
public string Difficulty { get; set; }
[JsonProperty("energy")]
public string Energy { get; set; }
[JsonProperty("energy")]
public string Energy { get; set; }
[JsonProperty("protein")]
public string Protein { get; set; }
[JsonProperty("protein")]
public string Protein { get; set; }
[JsonProperty("carbohydrates")]
public string Carbohydrates { get; set; }
[JsonProperty("carbohydrates")]
public string Carbohydrates { get; set; }
[JsonProperty("lipids")]
public string Lipids { get; set; }
[JsonProperty("lipids")]
public string Lipids { get; set; }
[JsonProperty("fiber")]
public string Fiber { get; set; }
[JsonProperty("fiber")]
public string Fiber { get; set; }
[JsonProperty("cholesterol")]
[JsonProperty("cholesterol")]
public string Cholesterol { get; set; }
[JsonProperty("ingredients")]
public IList<Ingredient> Ingredients { get; set; }
public string ExcerptQuotes => $"\"{Excerpt}\"";
public Recipe()
{
}
}
public Recipe() { }
}
}
......@@ -2,10 +2,10 @@
namespace inutralia.Models
{
[JsonObject (MemberSerialization.OptIn)]
[JsonObject(MemberSerialization.OptIn)]
public class RecipeOption : ObservableEntityData
{
[JsonProperty ("name", Required = Required.Always)]
[JsonProperty("name", Required = Required.Always)]
public string Name { get; set; }
public bool Selected { get; set; }
......
......@@ -3,8 +3,9 @@ using System.Collections.Generic;
namespace inutralia.Models
{
[JsonObject (MemberSerialization.OptIn)]
[DataPath ("options")]
[JsonObject(MemberSerialization.OptIn)]
[DataPath("options")]
public class RecipeOptionGroup : ObservableEntityData
{
private bool _isExpanded = false;
......@@ -22,10 +23,10 @@ namespace inutralia.Models
}
}
[JsonProperty ("name", Required = Required.Always)]
[JsonProperty("name", Required = Required.Always)]
public string Name { get; set; }
[JsonProperty ("options")]
[JsonProperty("options")]
public IList<RecipeOption> Options { get; set; }
}
}
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace inutralia.Models
{
[JsonObject(MemberSerialization.OptIn)]
[DataPath("shoppingList")]
public class ShoppingList : ObservableEntityData
{
[JsonProperty("text", Required = Required.Always)]
public string Text { get; set; }
public string Text { get; set; }
[JsonProperty("select", Required = Required.Always)]
public bool Select { get; set; }
......
......@@ -4,20 +4,21 @@ using System.Collections.Generic;
namespace inutralia.Models
{
[JsonObject (MemberSerialization.OptIn)]
[DataPath ("game")]
[JsonObject(MemberSerialization.OptIn)]
[DataPath("game")]
public class TrivialGame : ObservableEntityData
{
[JsonProperty ("start", Required = Required.Always)]
[JsonProperty("start", Required = Required.Always)]
public string StartDate { get; protected set; }
[JsonProperty ("finish", Required = Required.Always )]
[JsonProperty("finish", Required = Required.Always)]
public string FinishDate { get; protected set; }
[JsonProperty ("questions", Required = Required.Always)]
[JsonProperty("questions", Required = Required.Always)]
public IList<TrivialQuestion> Questions;
[JsonProperty ("answers", Required = Required.Always)]
[JsonProperty("answers", Required = Required.Always)]
public IList<int> Answers;
public string Progress => $"{Answers.Count} / {Questions.Count}";
......@@ -28,13 +29,13 @@ namespace inutralia.Models
{
// Si no está todo respondido, no hay puntuación
int n = Answers.Count;
if ( (n < Questions.Count) || (n < 1) )
if ((n < Questions.Count) || (n < 1))
return "";
// Calcular respuestas correctas
int correctas = 0;
for (int i = 0; i < n; i++)
if (Questions [i].ValidIndex == Answers [i])
if (Questions[i].ValidIndex == Answers[i])
correctas++;
// TODO: Otro mecanismo de score ?
......@@ -43,28 +44,26 @@ namespace inutralia.Models
}
}
public static TrivialGame Create ( IList<TrivialQuestion> questions)
public static TrivialGame Create(IList<TrivialQuestion> questions)
{
TrivialGame game = new TrivialGame ();
TrivialGame game = new TrivialGame();
game.Questions = questions;
game.Answers = new List<int> ();
game.Answers = new List<int>();
game.StartDate = DateTime.Now.ToString();
game.FinishDate = "";
return game;
}
public bool Answer ( int answer)
public bool Answer(int answer)
{
int n = Answers.Count;
if(n < Questions.Count)
if (n < Questions.Count)
{
Answers.Add (answer);
OnPropertyChanged ("Answers");
OnPropertyChanged ("Progress");
OnPropertyChanged ("Score");
return Questions [n].ValidIndex == answer;
Answers.Add(answer);
OnPropertyChanged("Answers");
OnPropertyChanged("Progress");
OnPropertyChanged("Score");
return Questions[n].ValidIndex == answer;
} //endif
return false;
......
......@@ -4,21 +4,22 @@ using System.ComponentModel;
namespace inutralia.Models
{
[JsonObject (MemberSerialization.OptIn)]
[DataPath ("trivial")]
[JsonObject(MemberSerialization.OptIn)]
[DataPath("trivial")]
public class TrivialQuestion : ObservableEntityData
{
[JsonProperty ("image", DefaultValueHandling = DefaultValueHandling.Populate)]
[JsonProperty("image", DefaultValueHandling = DefaultValueHandling.Populate)]
[DefaultValue("")]
public string Image { get; set; }
[JsonProperty ("text", Required = Required.Always)]
[JsonProperty("text", Required = Required.Always)]
public string Text { get; set; }
[JsonProperty ("options", Required = Required.Always)]
[JsonProperty("options", Required = Required.Always)]
public IList<string> Options { get; set; }
[JsonProperty ("valid", Required = Required.Always)]
[JsonProperty("valid", Required = Required.Always)]
public int ValidIndex { get; set; }
}
}

using Newtonsoft.Json;
using System.ComponentModel;
using System.Linq;
using System.Runtime.Serialization;
using Newtonsoft.Json;
namespace inutralia.Models
{
[JsonObject(MemberSerialization.OptIn)]
[DataPath("user")]
public class User : ObservableEntityData
{
public User()
{
[JsonObject(MemberSerialization.OptIn)]
[DataPath("user")]
}
}
public class User : ObservableEntityData
{
public User() { }
}
}
......@@ -3,39 +3,39 @@ using System.Globalization;
namespace inutralia.Utils
{
public static class DateUtilities
{
public static DateTime DateTimefromTimeStamp(int timestamp)
{
DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
dtDateTime = dtDateTime.AddSeconds(timestamp);
return dtDateTime;
}
public static class DateUtilities
{
public static DateTime DateTimefromTimeStamp(int timestamp)
{
DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
dtDateTime = dtDateTime.AddSeconds(timestamp);
return dtDateTime;
}
public static string formatedDateFromTimeStamp(int timestamp, string format = "dd/MM/YYYY")
{
DateTime time = DateTimefromTimeStamp(timestamp);
string d1 = DateTime.UtcNow.ToString("dd/MM/yyyy");
string d2 = time.ToString("dd/MM/yyyy");
if (d1 == d2)
{
format = "HH:mm";
}
return time.ToString(format);
}
public static string formatedDateFromTimeStamp(int timestamp, string format = "dd/MM/YYYY")
{
DateTime time = DateTimefromTimeStamp(timestamp);
string d1 = DateTime.UtcNow.ToString("dd/MM/yyyy");
string d2 = time.ToString("dd/MM/yyyy");
if (d1 == d2)
{
format = "HH:mm";
}
return time.ToString(format);
}
public static Int32 formatedDateToTimeStamp(string date, string format = "dd/mm/YYYY", CultureInfo CI = null)
{
if (CI == null)
{
CI = CultureInfo.CurrentCulture;
}
return formatedDateToTimeStamp(DateTime.ParseExact(date, format, CI));
}
public static Int32 formatedDateToTimeStamp(string date, string format = "dd/mm/YYYY", CultureInfo CI = null)
{
if (CI == null)
{
CI = CultureInfo.CurrentCulture;
}
return formatedDateToTimeStamp(DateTime.ParseExact(date, format, CI));
}
public static Int32 formatedDateToTimeStamp(DateTime date)
{
return (Int32)(date.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
}
}
public static Int32 formatedDateToTimeStamp(DateTime date)
{
return (Int32)(date.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
}
}
}
using System.Diagnostics;
using Foundation;
using UIKit;
using Xamarin.Forms;
using Lottie.Forms.iOS.Renderers;
using FFImageLoading.Forms.Touch;
using UXDivers.Artina.Shared;
namespace inutralia
{
// The UIApplicationDelegate for the application. This class is responsible for launching the
// User Interface of the application, as well as listening (and optionally responding) to application events from iOS.
[Register ("AppDelegate")]
public class AppDelegate : Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
Forms.Init ();
FFImageLoading.Forms.Platform.CachedImageRenderer.Init(); // Initializing FFImageLoading
AnimationViewRenderer.Init(); // Initializing Lottie
// The UIApplicationDelegate for the application. This class is responsible for launching the
// User Interface of the application, as well as listening (and optionally responding) to application events from iOS
[Register("AppDelegate")]
public class AppDelegate : Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
Forms.Init();
// Initializing FFImageLoading
FFImageLoading.Forms.Platform.CachedImageRenderer.Init();
// Initializing Lottie
AnimationViewRenderer.Init();
//Initializing GrialKit
GrialKit.Init(new ThemeColors(), "inutralia.GrialLicense");
UIApplication.SharedApplication.SetStatusBarHidden(true, true);
var tint = UIColor.White;
UIButton.AppearanceWhenContainedIn( typeof(UINavigationBar) ).TintColor = tint;
UIButton.AppearanceWhenContainedIn(typeof(UINavigationBar)).TintColor = tint;
app.SetStatusBarStyle(UIStatusBarStyle.LightContent, true);
//UINavigationBar.Appearance.SetTitleTextAttributes(new UITextAttributes{TextColor = UIColor.White});
UINavigationBar.Appearance.TintColor = UIColor.White;
FormsHelper.ForceLoadingAssemblyContainingType(typeof(UXDivers.Effects.Effects));
FormsHelper.ForceLoadingAssemblyContainingType<UXDivers.Effects.iOS.CircleEffect>();
LoadApplication(new App());
// Code for starting up the Xamarin Test Cloud Agent
#if ENABLE_TEST_CLOUD
Xamarin.Calabash.Start();
#endif
FormsHelper.ForceLoadingAssemblyContainingType(typeof(UXDivers.Effects.Effects));
FormsHelper.ForceLoadingAssemblyContainingType<UXDivers.Effects.iOS.CircleEffect>();
LoadApplication (new App ());
return base.FinishedLaunching (app, options);
}
}
return base.FinishedLaunching(app, options);
}
}
}
\ No newline at end of file
......@@ -2,14 +2,14 @@ using UIKit;
namespace inutralia
{
public class Application
{
// This is the main entry point of the application.
static void Main (string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main (args, null, "AppDelegate");
}
}
public class Application
{
// This is the main entry point of the application.
static void Main(string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main(args, null, "AppDelegate");
}
}
}
......@@ -197,10 +197,6 @@
</Reference>
<Reference Include="Xamarin.iOS" />
<Reference Include="System.Xml.Linq" />
<Reference Include="SkiaSharp">
<HintPath>..\packages\SkiaSharp.1.56.1\lib\XamariniOS\SkiaSharp.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<ImageAsset Include="Resources\Images.xcassets\AppIcons.appiconset\Contents.json">
......@@ -372,9 +368,6 @@
<BundleResource Include="Resources\icon_info.png" />
</ItemGroup>
<ItemGroup>
<BundleResource Include="icon_filter.png" />
</ItemGroup>
<ItemGroup>
<BundleResource Include="Resources\icon_filter.png" />
</ItemGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
......
......@@ -5,11 +5,10 @@ namespace inutralia.API
class Constants
{
public static readonly string ApiUrlTemplate =
Device.OnPlatform ("http://i20.inutralia.com/api/v1/{0}?api-key=7745289b-f09c-4e0b-89d1-bb59c599c85e",
Device.OnPlatform("http://i20.inutralia.com/api/v1/{0}?api-key=7745289b-f09c-4e0b-89d1-bb59c599c85e",
"http://i20.inutralia.com/api/v1/{0}?api-key=7745289b-f09c-4e0b-89d1-bb59c599c85e",
"http://i20.inutralia.com/api/v1/{0}?api-key=7745289b-f09c-4e0b-89d1-bb59c599c85e");
// Url redirect a DEL SUPER
public const string ApiUrl = "https://delsuper.es/inutralia?ids=";
......
......@@ -11,25 +11,25 @@ namespace inutralia.API
/// </summary>
public interface IWebService : IDataPersistenceService
{
/// <summary>
/// Borra la información relativa a las credenciales
/// </summary>
void Reset();
/// <summary>
/// Borra la información relativa a las credenciales
/// </summary>
void Reset();
/// <summary>
/// <summary>
/// Establece las credenciales de acceso a la API
/// </summary>
/// <param name="username">Nombre del usuario accediendo a la API</param>
/// <param name="password">Contraseña del usuario</param>
void CredentialsSet (string username, string password);
void CredentialsSet(string username, string password);
/// <summary>
/// Registra un usuario en el servidor
/// </summary>
/// <param name="userName">Nombre del usuario solicitando registro</param>
/// <param name="passWord">Contraseña del usuario solicitando registro</param>
/// <param name="companyCode">Código de la compañía que solicita el registro</param>
Task<HttpStatusCode?> RegisterUser(string userName, string passWord, string companyCode);
/// <summary>
/// Registra un usuario en el servidor
/// </summary>
/// <param name="userName">Nombre del usuario solicitando registro</param>
/// <param name="passWord">Contraseña del usuario solicitando registro</param>
/// <param name="companyCode">Código de la compañía que solicita el registro</param>
Task<HttpStatusCode?> RegisterUser(string userName, string passWord, string companyCode);
/// <summary>
/// Cambia la contraseña del usuario actual
......@@ -38,50 +38,50 @@ namespace inutralia.API
/// <param name="newPass">Nueva contraseña</param>
Task<bool> PasswordChange(string currPass, string newPass);
/// <summary>
/// Obtiene de forma asíncrona una lista de elementos de cierto tipo
/// </summary>
/// <typeparam name="T">Tipo de datos de cada elemento</typeparam>
/// <param name="path">Path de acceso al recurso de la API</param>
/// <returns>Lista de elementos obtenidos</returns>
Task<List<T>> RefreshListAsync<T>(string path);
/// <summary>
/// Obtiene de forma asíncrona una lista de elementos de cierto tipo
/// </summary>
/// <typeparam name="T">Tipo de datos de cada elemento</typeparam>
/// <param name="path">Path de acceso al recurso de la API</param>
/// <returns>Lista de elementos obtenidos</returns>
Task<List<T>> RefreshListAsync<T>(string path);
/// <summary>
/// Petición directa al WebService
/// </summary>
/// <param name="method">Método HTTP de la petición</param>
/// <param name="resourcePath">Path del recurso REST al cual acceder</param>
/// <param name="data">Objeto a serializar en la petición</param>
/// <returns>Respuesta del servidor</returns>
Task<HttpResponseMessage> RawMessage(HttpMethod method, string resourcePath, object data = null);
/// <summary>
/// Petición directa al WebService
/// </summary>
/// <param name="method">Método HTTP de la petición</param>
/// <param name="resourcePath">Path del recurso REST al cual acceder</param>
/// <param name="data">Objeto a serializar en la petición</param>
/// <returns>Respuesta del servidor</returns>
Task<HttpResponseMessage> RawMessage(HttpMethod method, string resourcePath, object data = null);
/// <summary>
/// Petición directa al WebService (GET)
/// </summary>
/// <param name="resourcePath">Path del recurso REST al cual acceder</param>
/// <param name="data">Objeto a serializar en la petición</param>
/// <returns>Respuesta del servidor</returns>
Task<HttpResponseMessage> RawMessage(string resourcePath, object data = null);
/// <summary>
/// Petición directa al WebService (GET)
/// </summary>
/// <param name="resourcePath">Path del recurso REST al cual acceder</param>
/// <param name="data">Objeto a serializar en la petición</param>
/// <returns>Respuesta del servidor</returns>
Task<HttpResponseMessage> RawMessage(string resourcePath, object data = null);
/// <summary>
/// Procesa la respuesta de una petición directa
/// </summary>
/// <typeparam name="T">Tipo de datos en el que convertir los datos de respuesta</typeparam>
/// <param name="response">Respuesta devuelta por RawMessage</param>
/// <param name="data">Objeto a poblar con los datos de respuesta. Se creará un nuevo objeto si este parámetro es null</param>
/// <returns>El objeto poblado / creado. Si el status de la petición no es 2XX se devuelve null</returns>
Task<T> ResponseProcess<T>(HttpResponseMessage response, T data = null) where T : class;
/// <summary>
/// Procesa la respuesta de una petición directa
/// </summary>
/// <typeparam name="T">Tipo de datos en el que convertir los datos de respuesta</typeparam>
/// <param name="response">Respuesta devuelta por RawMessage</param>
/// <param name="data">Objeto a poblar con los datos de respuesta. Se creará un nuevo objeto si este parámetro es null</param>
/// <returns>El objeto poblado / creado. Si el status de la petición no es 2XX se devuelve null</returns>
Task<T> ResponseProcess<T>(HttpResponseMessage response, T data = null) where T : class;
/// <summary>
/// Realiza un petición directa y procesa su respuesta
/// </summary>
/// <typeparam name="T">Tipo de datos en el que convertir los datos de respuesta</typeparam>
/// <param name="method">Método HTTP de la petición</param>
/// <param name="resourcePath">Path del recurso REST al cual acceder</param>
/// <param name="input">Objeto a serializar en la petición</param>
/// <param name="output">Objeto a poblar con los datos de respuesta. Se creará un nuevo objeto si este parámetro es null</param>
/// <returns>El objeto poblado / creado. Si el status de la petición no es 2XX se devuelve null</returns>
Task<T> RawMessage<T>(HttpMethod method, string resourcePath, object input = null, T output = null) where T : class;
/// <summary>
/// Realiza un petición directa y procesa su respuesta
/// </summary>
/// <typeparam name="T">Tipo de datos en el que convertir los datos de respuesta</typeparam>
/// <param name="method">Método HTTP de la petición</param>
/// <param name="resourcePath">Path del recurso REST al cual acceder</param>
/// <param name="input">Objeto a serializar en la petición</param>
/// <param name="output">Objeto a poblar con los datos de respuesta. Se creará un nuevo objeto si este parámetro es null</param>
/// <returns>El objeto poblado / creado. Si el status de la petición no es 2XX se devuelve null</returns>
Task<T> RawMessage<T>(HttpMethod method, string resourcePath, object input = null, T output = null) where T : class;
}
}
......@@ -5,9 +5,7 @@ using Plugin.Settings;
using Plugin.Settings.Abstractions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace inutralia.API
......@@ -22,96 +20,96 @@ namespace inutralia.API
#pragma warning disable CS1998 // Sabemos que no vamos a poner await en los métodos async, por lo que deshabilitamos el warning
public async Task<bool> DeleteItemAsync<T> (T item) where T : IIdentifiableEntity
public async Task<bool> DeleteItemAsync<T>(T item) where T : IIdentifiableEntity
{
Type type = item.GetType ();
string path = GetItemPath (item);
if(AppSettings.Contains(path))
Type type = item.GetType();
string path = GetItemPath(item);
if (AppSettings.Contains(path))
{
// Eliminar elemento
AppSettings.Remove (path);
AppSettings.Remove(path);
// Eliminar de la lista de elementos
var list = GetIdList (type);
list.Remove (item.Id);
SetIdList (type, list);
var list = GetIdList(type);
list.Remove(item.Id);
SetIdList(type, list);
} //endif
return true;
}
public async Task<T> GetItemAsync<T> (int id) where T : IIdentifiableEntity
public async Task<T> GetItemAsync<T>(int id) where T : IIdentifiableEntity
{
string path = string.Format ("Models/{0}/{1}", GetDataPath (typeof (T)), id);
if(AppSettings.Contains(path))
string path = string.Format("Models/{0}/{1}", GetDataPath(typeof(T)), id);
if (AppSettings.Contains(path))
{
var content = AppSettings.GetValueOrDefault<string> (path);
return JsonConvert.DeserializeObject<T> (content);
var content = AppSettings.GetValueOrDefault<string>(path);
return JsonConvert.DeserializeObject<T>(content);
} //endif
return default (T);
return default(T);
}
public async Task<bool> RefreshItemAsync<T> (T item) where T : IIdentifiableEntity
public async Task<bool> RefreshItemAsync<T>(T item) where T : IIdentifiableEntity
{
string path = GetItemPath (item);
if(AppSettings.Contains(path))
string path = GetItemPath(item);
if (AppSettings.Contains(path))
{
var content = AppSettings.GetValueOrDefault<string> (path);
JsonConvert.PopulateObject (content, item);
var content = AppSettings.GetValueOrDefault<string>(path);
JsonConvert.PopulateObject(content, item);
return true;
} //endif
return false;
}
public async Task<List<T>> RefreshListAsync<T> () where T : IIdentifiableEntity
public async Task<List<T>> RefreshListAsync<T>() where T : IIdentifiableEntity
{
Type type = typeof (T);
string basePath = GetDataPath (type);
List<int> idList = GetIdList (type);
List<T> retVal = new List<T> ();
List<int> idsToRemove = new List<int> ();
Type type = typeof(T);
string basePath = GetDataPath(type);
List<int> idList = GetIdList(type);
List<T> retVal = new List<T>();
List<int> idsToRemove = new List<int>();
foreach(int id in idList)
foreach (int id in idList)
{
string path = string.Format ("Models/{0}/{1}", basePath, id);
if (AppSettings.Contains (path))
string path = string.Format("Models/{0}/{1}", basePath, id);
if (AppSettings.Contains(path))
{
var content = AppSettings.GetValueOrDefault<string> (path);
retVal.Add (JsonConvert.DeserializeObject<T> (content));
var content = AppSettings.GetValueOrDefault<string>(path);
retVal.Add(JsonConvert.DeserializeObject<T>(content));
}
else
{
idsToRemove.Add (id);
idsToRemove.Add(id);
} //endif
} //endforeach
if(idsToRemove.Count > 0)
if (idsToRemove.Count > 0)
{
// Borrar de la lista inicial los que haya que elilminar, y guardar la lista
idList.RemoveAll ((i) => { return idsToRemove.Contains (i); });
SetIdList (type, idList);
idList.RemoveAll((i) => { return idsToRemove.Contains(i); });
SetIdList(type, idList);
} //endif
return retVal;
}
public async Task<int?> UpdateItemAsync<T> (T item, bool isNew = false) where T : IIdentifiableEntity
public async Task<int?> UpdateItemAsync<T>(T item, bool isNew = false) where T : IIdentifiableEntity
{
if(isNew)
if (isNew)
{
// Elemento nuevo: asignarle Id. Cogemos la lista de ids ...
List<int> idList = GetIdList (item.GetType ());
List<int> idList = GetIdList(item.GetType());
// ... buscamos el máximo y le sumamos 1
//item.Id = (idList.Count < 1) ? 1 : idList.Max () + 1;
// ... añadimos el nuevo id a la lista
idList.Add (item.Id);
idList.Add(item.Id);
// ... y la guardamos
SetIdList (item.GetType (), idList);
SetIdList(item.GetType(), idList);
}
else if (!AppSettings.Contains(GetItemPath(item)))
{
......@@ -120,7 +118,7 @@ namespace inutralia.API
} //endif
// Guardar elemento
AppSettings.AddOrUpdateValue (GetItemPath (item), JsonConvert.SerializeObject (item));
AppSettings.AddOrUpdateValue(GetItemPath(item), JsonConvert.SerializeObject(item));
// Retornar su id
return item.Id;
......@@ -128,38 +126,38 @@ namespace inutralia.API
#pragma warning restore CS1998 // Sabemos que no vamos a poner await en los métodos async, por lo que deshabilitamos el warning
private static List<int> GetIdList (Type t, List<int> listToFill = null)
private static List<int> GetIdList(Type t, List<int> listToFill = null)
{
// Crear lista si no nos pasan ninguna. Vaciarla.
List<int> retVal = listToFill ?? new List<int> ();
retVal.Clear ();
List<int> retVal = listToFill ?? new List<int>();
retVal.Clear();
// Leer lista de ids (sólo si existe)
string path = string.Format ("ModelIdList/{0}", GetDataPath (t));
if (AppSettings.Contains (path))
string path = string.Format("ModelIdList/{0}", GetDataPath(t));
if (AppSettings.Contains(path))
{
// Deserializar valor json
string value = AppSettings.GetValueOrDefault<string> (path);
JsonConvert.PopulateObject (value, retVal);
string value = AppSettings.GetValueOrDefault<string>(path);
JsonConvert.PopulateObject(value, retVal);
} //endif
return retVal;
}
private static void SetIdList (Type t, List<int> idList)
private static void SetIdList(Type t, List<int> idList)
{
string path = string.Format ("ModelIdList/{0}", GetDataPath (t));
string path = string.Format("ModelIdList/{0}", GetDataPath(t));
if ((idList == null) || (idList.Count < 1))
{
// Si la lista está vacía, borrar la entrada de settings
AppSettings.Remove (path);
AppSettings.Remove(path);
}
else
{
// Serializar con JSON y guardar
string value = JsonConvert.SerializeObject (idList);
AppSettings.AddOrUpdateValue (path, value);
string value = JsonConvert.SerializeObject(idList);
AppSettings.AddOrUpdateValue(path, value);
} //endif
}
......@@ -168,15 +166,15 @@ namespace inutralia.API
/// </summary>
/// <param name="t">Tipo de dato de la entidad</typeparam>
/// <returns>El path correspondiente dentro del API</returns>
private static string GetDataPath (Type t)
private static string GetDataPath(Type t)
{
// Si tiene el atributo DataPath, lo utilizamos
DataPathAttribute attr = t.GetTypeInfo ().GetCustomAttribute<DataPathAttribute> ();
DataPathAttribute attr = t.GetTypeInfo().GetCustomAttribute<DataPathAttribute>();
if (attr != null)
return attr.DataPath;
// En caso contrario devolvemos el nombre de la clase en minúsculas y en plural
return t.Name.ToLowerInvariant () + "s";
return t.Name.ToLowerInvariant() + "s";
}
/// <summary>
......@@ -185,11 +183,9 @@ namespace inutralia.API
/// <typeparam name="T"></typeparam>
/// <param name="item"></param>
/// <returns></returns>
private static string GetItemPath<T> (T item) where T: IIdentifiableEntity
private static string GetItemPath<T>(T item) where T : IIdentifiableEntity
{
return string.Format ("Models/{0}/{1}", GetDataPath (item.GetType ()), item.Id);
return string.Format("Models/{0}/{1}", GetDataPath(item.GetType()), item.Id);
}
}
}
......@@ -2,8 +2,6 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace inutralia
......@@ -12,42 +10,42 @@ namespace inutralia
{
private List<Color> _Colors;
public AlternatingBackgroundColorConverter (string commaSeparatedColors)
public AlternatingBackgroundColorConverter(string commaSeparatedColors)
{
var conv = new ColorTypeConverter ();
var conv = new ColorTypeConverter();
string [] colors = commaSeparatedColors.Split (',');
string[] colors = commaSeparatedColors.Split(',');
_Colors = new List<Color> ();
_Colors = new List<Color>();
foreach (string s in colors)
{
try
{
if (s.Length > 0)
_Colors.Add ((Color) conv.ConvertFromInvariantString (s));
_Colors.Add((Color)conv.ConvertFromInvariantString(s));
}
catch (Exception)
{ }
} //endforeach
}
public object Convert (object value, Type targetType, object parameter, CultureInfo culture)
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
// Si no hay lista de colores o los parámetros no son correctos => transparente
if( (value == null) || (parameter == null) || (_Colors.Count < 1) )
if ((value == null) || (parameter == null) || (_Colors.Count < 1))
return Color.Transparent;
// Obtener índice del elemento en la lista
var index = ((ListView) parameter).ItemsSource.Cast<object> ().ToList ().IndexOf (value);
var index = ((ListView)parameter).ItemsSource.Cast<object>().ToList().IndexOf(value);
// Retornar el color que corresponda
return _Colors [index % _Colors.Count];
return _Colors[index % _Colors.Count];
}
public object ConvertBack (object value, Type targetType, object parameter, CultureInfo culture)
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException ();
throw new NotImplementedException();
}
}
}
......@@ -7,7 +7,6 @@ namespace inutralia
{
public class DateTransformator : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return DateUtilities.formatedDateFromTimeStamp((int)value, parameter != null ? parameter as string : culture.DateTimeFormat.ShortDatePattern);
......
......@@ -5,12 +5,11 @@ using Xamarin.Forms;
namespace inutralia.Converters
{
class ImageTransformator: IValueConverter
class ImageTransformator : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return ImageSource.FromStream (() => new MemoryStream(System.Convert.FromBase64String ((string)value)));
return ImageSource.FromStream(() => new MemoryStream(System.Convert.FromBase64String((string)value)));
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
......
// Helpers/Settings.cs
using Plugin.Settings;
using Plugin.Settings.Abstractions;
namespace inutralia.Helpers
{
/// <summary>
/// This is the Settings static class that can be used in your Core solution or in any
/// of your client applications. All settings are laid out the same exact way with getters
/// and setters.
/// </summary>
public static class Settings
{
private static ISettings AppSettings
/// <summary>
/// This is the Settings static class that can be used in your Core solution or in any
/// of your client applications. All settings are laid out the same exact way with getters
/// and setters.
/// </summary>
public static class Settings
{
get
{
return CrossSettings.Current;
}
}
#region Setting Constants
private static ISettings AppSettings
{
get
{
return CrossSettings.Current;
}
}
private const string SettingsKey = "settings_key";
private static readonly string SettingsDefault = string.Empty;
#region Setting Constants
#endregion
private const string SettingsKey = "settings_key";
private static readonly string SettingsDefault = string.Empty;
#endregion
public static string GeneralSettings
{
get
{
return AppSettings.GetValueOrDefault<string>(SettingsKey, SettingsDefault);
}
set
{
AppSettings.AddOrUpdateValue<string>(SettingsKey, value);
}
public static string GeneralSettings
{
get
{
return AppSettings.GetValueOrDefault<string>(SettingsKey, SettingsDefault);
}
set
{
AppSettings.AddOrUpdateValue<string>(SettingsKey, value);
}
}
}
}
}
\ No newline at end of file
using System;
namespace inutralia
{
public static class AssemblyGlobal
{
public const string Company = "UXDivers";
public static class AssemblyGlobal
{
public const string Company = "UXDivers";
public const string ProductLine = "Grial UIKit";
public const string ProductLine = "Grial UIKit";
public const string Year = "2017";
public const string Year = "2017";
public const string Copyright = Company + " - " + Year;
public const string Copyright = Company + " - " + Year;
#if DEBUG
public const string Configuration = "Debug";
public const string Configuration = "Debug";
#elif RELEASE
public const string Configuration = "Release";
#else
public const string Configuration = "Unkown";
#endif
}
}
}
......@@ -2,11 +2,9 @@ using System.Reflection;
using Xamarin.Forms.Xaml;
using inutralia;
[assembly: AssemblyTitle (AssemblyGlobal.ProductLine + " - " + "Grial Xamarin.Forms UIKit")]
[assembly: AssemblyConfiguration (AssemblyGlobal.Configuration)]
[assembly: AssemblyCompany (AssemblyGlobal.Company)]
[assembly: AssemblyProduct (AssemblyGlobal.ProductLine + " - " + "Grial Xamarin.Forms UIKit")]
[assembly: AssemblyCopyright (AssemblyGlobal.Copyright)]
[assembly: XamlCompilation (XamlCompilationOptions.Compile)]
\ No newline at end of file
[assembly: AssemblyTitle(AssemblyGlobal.ProductLine + " - " + "Grial Xamarin.Forms UIKit")]
[assembly: AssemblyConfiguration(AssemblyGlobal.Configuration)]
[assembly: AssemblyCompany(AssemblyGlobal.Company)]
[assembly: AssemblyProduct(AssemblyGlobal.ProductLine + " - " + "Grial Xamarin.Forms UIKit")]
[assembly: AssemblyCopyright(AssemblyGlobal.Copyright)]
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
\ No newline at end of file
......@@ -4,7 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="inutralia.GrialDarkTheme">
<!--
<!--
THEME COLORS
The colors below will be automatically updated on each platform project by the build task.
......@@ -19,69 +19,62 @@
...but this is:
#FF169CEE
-->
<!-- Grial Theme Exported Colors -->
<Color x:Key="AccentColor">#FFDA125F</Color>
<Color x:Key="BaseTextColor">#D6E1F1</Color>
<!-- GENERAL COLORS -->
<Color x:Key="InverseTextColor">White</Color>
<Color x:Key="BrandColor">#ad1457</Color>
<Color x:Key="BrandNameColor">#FFFFFF</Color>
<Color x:Key="BaseLightTextColor">#7b7b7b</Color>
<Color x:Key="OverImageTextColor">#FFFFFF</Color>
<Color x:Key="EcommercePromoTextColor">#FFFFFF</Color>
<Color x:Key="SocialHeaderTextColor">#62527A</Color>
<Color x:Key="ArticleHeaderBackgroundColor">#1B1D22</Color>
<Color x:Key="CustomNavBarTextColor">#FFFFFF</Color>
<Color x:Key="ListViewItemTextColor">#FFFFFF</Color>
<Color x:Key="AboutHeaderBackgroundColor">#FFFFFF</Color>
<Color x:Key="BasePageColor">#282C37</Color>
<Color x:Key="BaseTabbedPageColor">#213D55</Color>
<Color x:Key="MainWrapperBackgroundColor">#1B1D22</Color>
<Color x:Key="CategoriesListIconColor">#55000000</Color>
<Color x:Key="DashboardIconColor">#FFFFFF</Color>
<!-- COMPLEMENT COLORS -->
<Color x:Key="ComplementColor">#525ABB</Color>
<Color x:Key="TranslucidBlack">#44000000</Color>
<Color x:Key="TranslucidWhite">#22ffffff</Color>
<!-- INDICATOR COLORS -->
<Color x:Key="OkColor">#22c064</Color>
<Color x:Key="ErrorColor">Red</Color>
<Color x:Key="WarningColor">#ffc107</Color>
<Color x:Key="NotificationColor">#1274d1</Color>
<!-- BUTTONS & ENTRY COLORS -->
<Color x:Key="SaveButtonColor">#22c064</Color>
<Color x:Key="DeleteButtonColor">#D50000</Color>
<Color x:Key="LabelButtonColor">#ffffff</Color>
<Color x:Key="PlaceholderColor">#FFFFFF</Color>
<Color x:Key="PlaceholderColorEntry">#505971</Color>
<Color x:Key="RoundedLabelBackgroundColor">#525ABB</Color>
<!-- MAIN MENU COLORS -->
<Color x:Key="MainMenuHeaderBackgroundColor">Transparent</Color>
<Color x:Key="MainMenuBackgroundColor">#1B1F2A</Color>
<Color x:Key="MainMenuSeparatorColor">Transparent</Color>
<Color x:Key="MainMenuTextColor">#D6E1F1</Color>
<Color x:Key="MainMenuIconColor">#D6E1F1</Color>
<!-- SEPARATORS COLORS -->
<Color x:Key="ListViewSeparatorColor">#151C22</Color>
<Color x:Key="BaseSeparatorColor">#7b7b7b</Color>
<!-- CHAT COLORS -->
<Color x:Key="ChatRightBalloonBackgroundColor">#525ABB</Color>
<Color x:Key="ChatBalloonFooterTextColor">#FFFFFF</Color>
<Color x:Key="ChatRightTextColor">#FFFFFF</Color>
<Color x:Key="ChatLeftTextColor">#FFFFFF</Color>
<!-- Grial Theme Exported Colors -->
<Color x:Key="AccentColor">#FFDA125F</Color>
<Color x:Key="BaseTextColor">#D6E1F1</Color>
<!-- GENERAL COLORS -->
<Color x:Key="InverseTextColor">White</Color>
<Color x:Key="BrandColor">#ad1457</Color>
<Color x:Key="BrandNameColor">#FFFFFF</Color>
<Color x:Key="BaseLightTextColor">#7b7b7b</Color>
<Color x:Key="OverImageTextColor">#FFFFFF</Color>
<Color x:Key="EcommercePromoTextColor">#FFFFFF</Color>
<Color x:Key="SocialHeaderTextColor">#62527A</Color>
<Color x:Key="ArticleHeaderBackgroundColor">#1B1D22</Color>
<Color x:Key="CustomNavBarTextColor">#FFFFFF</Color>
<Color x:Key="ListViewItemTextColor">#FFFFFF</Color>
<Color x:Key="AboutHeaderBackgroundColor">#FFFFFF</Color>
<Color x:Key="BasePageColor">#282C37</Color>
<Color x:Key="BaseTabbedPageColor">#213D55</Color>
<Color x:Key="MainWrapperBackgroundColor">#1B1D22</Color>
<Color x:Key="CategoriesListIconColor">#55000000</Color>
<Color x:Key="DashboardIconColor">#FFFFFF</Color>
<!-- COMPLEMENT COLORS -->
<Color x:Key="ComplementColor">#525ABB</Color>
<Color x:Key="TranslucidBlack">#44000000</Color>
<Color x:Key="TranslucidWhite">#22ffffff</Color>
<!-- INDICATOR COLORS -->
<Color x:Key="OkColor">#22c064</Color>
<Color x:Key="ErrorColor">Red</Color>
<Color x:Key="WarningColor">#ffc107</Color>
<Color x:Key="NotificationColor">#1274d1</Color>
<!-- BUTTONS & ENTRY COLORS -->
<Color x:Key="SaveButtonColor">#22c064</Color>
<Color x:Key="DeleteButtonColor">#D50000</Color>
<Color x:Key="LabelButtonColor">#ffffff</Color>
<Color x:Key="PlaceholderColor">#FFFFFF</Color>
<Color x:Key="PlaceholderColorEntry">#505971</Color>
<Color x:Key="RoundedLabelBackgroundColor">#525ABB</Color>
<!-- MAIN MENU COLORS -->
<Color x:Key="MainMenuHeaderBackgroundColor">Transparent</Color>
<Color x:Key="MainMenuBackgroundColor">#1B1F2A</Color>
<Color x:Key="MainMenuSeparatorColor">Transparent</Color>
<Color x:Key="MainMenuTextColor">#D6E1F1</Color>
<Color x:Key="MainMenuIconColor">#D6E1F1</Color>
<!-- SEPARATORS COLORS -->
<Color x:Key="ListViewSeparatorColor">#151C22</Color>
<Color x:Key="BaseSeparatorColor">#7b7b7b</Color>
<!-- CHAT COLORS -->
<Color x:Key="ChatRightBalloonBackgroundColor">#525ABB</Color>
<Color x:Key="ChatBalloonFooterTextColor">#FFFFFF</Color>
<Color x:Key="ChatRightTextColor">#FFFFFF</Color>
<Color x:Key="ChatLeftTextColor">#FFFFFF</Color>
</ResourceDictionary>
using System;
using System.Collections.Generic;
using Xamarin.Forms;
namespace inutralia
{
public partial class GrialDarkTheme
{
public GrialDarkTheme()
{
InitializeComponent();
}
}
public partial class GrialDarkTheme
{
public GrialDarkTheme()
{
InitializeComponent();
}
}
}
......@@ -4,7 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="inutralia.GrialEnterpriseTheme">
<!--
<!--
THEME COLORS
The colors below will be automatically updated on each platform project by the build task.
......@@ -19,69 +19,63 @@
...but this is:
#FF169CEE
-->
<!-- Grial Theme Exported Colors -->
<Color x:Key="AccentColor">#FF25BC99</Color>
<Color x:Key="BaseTextColor">#FFFFFF</Color>
<!-- GENERAL COLORS -->
<Color x:Key="InverseTextColor">White</Color>
<Color x:Key="BrandColor">#1F8269</Color>
<Color x:Key="BrandNameColor">#FFFFFF</Color>
<Color x:Key="BaseLightTextColor">#7b7b7b</Color>
<Color x:Key="OverImageTextColor">#FFFFFF</Color>
<Color x:Key="EcommercePromoTextColor">#FFFFFF</Color>
<Color x:Key="SocialHeaderTextColor">#666666</Color>
<Color x:Key="ArticleHeaderBackgroundColor">#344860</Color>
<Color x:Key="CustomNavBarTextColor">#FFFFFF</Color>
<Color x:Key="ListViewItemTextColor">#666666</Color>
<Color x:Key="AboutHeaderBackgroundColor">#FFFFFF</Color>
<Color x:Key="BasePageColor">#1A2634</Color>
<Color x:Key="BaseTabbedPageColor">#fafafa</Color>
<Color x:Key="MainWrapperBackgroundColor">#1B1D22</Color>
<Color x:Key="CategoriesListIconColor">#55000000</Color>
<Color x:Key="DashboardIconColor">#FFFFFF</Color>
<!-- COMPLEMENT COLORS -->
<Color x:Key="ComplementColor">#525ABB</Color>
<Color x:Key="TranslucidBlack">#44000000</Color>
<Color x:Key="TranslucidWhite">#22ffffff</Color>
<!-- INDICATOR COLORS -->
<Color x:Key="OkColor">#22c064</Color>
<Color x:Key="ErrorColor">Red</Color>
<Color x:Key="WarningColor">#ffc107</Color>
<Color x:Key="NotificationColor">#1274d1</Color>
<!-- BUTTONS & ENTRY COLORS -->
<Color x:Key="SaveButtonColor">#22c064</Color>
<Color x:Key="DeleteButtonColor">#D50000</Color>
<Color x:Key="LabelButtonColor">#ffffff</Color>
<Color x:Key="PlaceholderColor">#ffffff</Color>
<Color x:Key="PlaceholderColorEntry">#344860</Color>
<Color x:Key="RoundedLabelBackgroundColor">#122336</Color>
<!-- MAIN MENU COLORS -->
<Color x:Key="MainMenuHeaderBackgroundColor">#384F63</Color>
<Color x:Key="MainMenuBackgroundColor">#344860</Color>
<Color x:Key="MainMenuSeparatorColor">Transparent</Color>
<Color x:Key="MainMenuTextColor">#FFFFFF</Color>
<Color x:Key="MainMenuIconColor">#FFFFFF</Color>
<!-- SEPARATORS COLORS -->
<Color x:Key="ListViewSeparatorColor">#1B1D22</Color>
<Color x:Key="BaseSeparatorColor">#7b7b7b</Color>
<!-- CHAT COLORS -->
<Color x:Key="ChatRightBalloonBackgroundColor">#525ABB</Color>
<Color x:Key="ChatBalloonFooterTextColor">#FFFFFF</Color>
<Color x:Key="ChatRightTextColor">#FFFFFF</Color>
<Color x:Key="ChatLeftTextColor">#FFFFFF</Color>
<!-- Grial Theme Exported Colors -->
<Color x:Key="AccentColor">#FF25BC99</Color>
<Color x:Key="BaseTextColor">#FFFFFF</Color>
<!-- GENERAL COLORS -->
<Color x:Key="InverseTextColor">White</Color>
<Color x:Key="BrandColor">#1F8269</Color>
<Color x:Key="BrandNameColor">#FFFFFF</Color>
<Color x:Key="BaseLightTextColor">#7b7b7b</Color>
<Color x:Key="OverImageTextColor">#FFFFFF</Color>
<Color x:Key="EcommercePromoTextColor">#FFFFFF</Color>
<Color x:Key="SocialHeaderTextColor">#666666</Color>
<Color x:Key="ArticleHeaderBackgroundColor">#344860</Color>
<Color x:Key="CustomNavBarTextColor">#FFFFFF</Color>
<Color x:Key="ListViewItemTextColor">#666666</Color>
<Color x:Key="AboutHeaderBackgroundColor">#FFFFFF</Color>
<Color x:Key="BasePageColor">#1A2634</Color>
<Color x:Key="BaseTabbedPageColor">#fafafa</Color>
<Color x:Key="MainWrapperBackgroundColor">#1B1D22</Color>
<Color x:Key="CategoriesListIconColor">#55000000</Color>
<Color x:Key="DashboardIconColor">#FFFFFF</Color>
<!-- COMPLEMENT COLORS -->
<Color x:Key="ComplementColor">#525ABB</Color>
<Color x:Key="TranslucidBlack">#44000000</Color>
<Color x:Key="TranslucidWhite">#22ffffff</Color>
<!-- INDICATOR COLORS -->
<Color x:Key="OkColor">#22c064</Color>
<Color x:Key="ErrorColor">Red</Color>
<Color x:Key="WarningColor">#ffc107</Color>
<Color x:Key="NotificationColor">#1274d1</Color>
<!-- BUTTONS & ENTRY COLORS -->
<Color x:Key="SaveButtonColor">#22c064</Color>
<Color x:Key="DeleteButtonColor">#D50000</Color>
<Color x:Key="LabelButtonColor">#ffffff</Color>
<Color x:Key="PlaceholderColor">#ffffff</Color>
<Color x:Key="PlaceholderColorEntry">#344860</Color>
<Color x:Key="RoundedLabelBackgroundColor">#122336</Color>
<!-- MAIN MENU COLORS -->
<Color x:Key="MainMenuHeaderBackgroundColor">#384F63</Color>
<Color x:Key="MainMenuBackgroundColor">#344860</Color>
<Color x:Key="MainMenuSeparatorColor">Transparent</Color>
<Color x:Key="MainMenuTextColor">#FFFFFF</Color>
<Color x:Key="MainMenuIconColor">#FFFFFF</Color>
<!-- SEPARATORS COLORS -->
<Color x:Key="ListViewSeparatorColor">#1B1D22</Color>
<Color x:Key="BaseSeparatorColor">#7b7b7b</Color>
<!-- CHAT COLORS -->
<Color x:Key="ChatRightBalloonBackgroundColor">#525ABB</Color>
<Color x:Key="ChatBalloonFooterTextColor">#FFFFFF</Color>
<Color x:Key="ChatRightTextColor">#FFFFFF</Color>
<Color x:Key="ChatLeftTextColor">#FFFFFF</Color>
</ResourceDictionary>
using System;
using System.Collections.Generic;
using Xamarin.Forms;
namespace inutralia
{
public partial class GrialEnterpriseTheme
{
public GrialEnterpriseTheme()
{
InitializeComponent();
}
}
public partial class GrialEnterpriseTheme
{
public GrialEnterpriseTheme()
{
InitializeComponent();
}
}
}
......@@ -4,7 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="inutralia.GrialLightTheme">
<!--
<!--
THEME COLORS
The colors below will be automatically updated on each platform project by the build task.
......@@ -19,69 +19,65 @@
...but this is:
#FF169CEE
-->
<!-- Grial Theme Exported Colors -->
<Color x:Key="AccentColor">#FFDA125F</Color>
<Color x:Key="BaseTextColor">#666666</Color>
<!-- GENERAL COLORS -->
<Color x:Key="InverseTextColor">White</Color>
<Color x:Key="BrandColor">#ad1457</Color>
<Color x:Key="BrandNameColor">#FFFFFF</Color>
<Color x:Key="BaseLightTextColor">#7b7b7b</Color>
<Color x:Key="OverImageTextColor">#FFFFFF</Color>
<Color x:Key="EcommercePromoTextColor">#FFFFFF</Color>
<Color x:Key="SocialHeaderTextColor">#666666</Color>
<Color x:Key="ArticleHeaderBackgroundColor">#F1F3F5</Color>
<Color x:Key="CustomNavBarTextColor">#FFFFFF</Color>
<Color x:Key="ListViewItemTextColor">#666666</Color>
<Color x:Key="AboutHeaderBackgroundColor">#FFFFFF</Color>
<Color x:Key="BasePageColor">#FFFFFF</Color>
<Color x:Key="BaseTabbedPageColor">#fafafa</Color>
<Color x:Key="MainWrapperBackgroundColor">#EFEFEF</Color>
<Color x:Key="CategoriesListIconColor">#55000000</Color>
<Color x:Key="DashboardIconColor">#FFFFFF</Color>
<!-- COMPLEMENT COLORS -->
<Color x:Key="ComplementColor">#525ABB</Color>
<Color x:Key="TranslucidBlack">#44000000</Color>
<Color x:Key="TranslucidWhite">#22ffffff</Color>
<!-- INDICATOR COLORS -->
<Color x:Key="OkColor">#22c064</Color>
<Color x:Key="ErrorColor">Red</Color>
<Color x:Key="WarningColor">#ffc107</Color>
<Color x:Key="NotificationColor">#1274d1</Color>
<!-- BUTTONS & ENTRY COLORS -->
<Color x:Key="SaveButtonColor">#22c064</Color>
<Color x:Key="DeleteButtonColor">#D50000</Color>
<Color x:Key="LabelButtonColor">#ffffff</Color>
<Color x:Key="PlaceholderColor">#22ffffff</Color>
<Color x:Key="PlaceholderColorEntry">#FFFFFF</Color>
<Color x:Key="RoundedLabelBackgroundColor">#525ABB</Color>
<!-- MAIN MENU COLORS -->
<Color x:Key="MainMenuHeaderBackgroundColor">#384F63</Color>
<Color x:Key="MainMenuBackgroundColor">#F1F3F5</Color>
<Color x:Key="MainMenuSeparatorColor">Transparent</Color>
<Color x:Key="MainMenuTextColor">#666666</Color>
<Color x:Key="MainMenuIconColor">#666666</Color>
<!-- SEPARATORS COLORS -->
<Color x:Key="ListViewSeparatorColor">#D3D3D3</Color>
<Color x:Key="BaseSeparatorColor">#7b7b7b</Color>
<!-- CHAT COLORS -->
<Color x:Key="ChatRightBalloonBackgroundColor">#525ABB</Color>
<Color x:Key="ChatBalloonFooterTextColor">#FFFFFF</Color>
<Color x:Key="ChatRightTextColor">#FFFFFF</Color>
<Color x:Key="ChatLeftTextColor">#FFFFFF</Color>
<!-- Grial Theme Exported Colors -->
<Color x:Key="AccentColor">#FFDA125F</Color>
<Color x:Key="BaseTextColor">#666666</Color>
<!-- GENERAL COLORS -->
<Color x:Key="InverseTextColor">White</Color>
<Color x:Key="BrandColor">#ad1457</Color>
<Color x:Key="BrandNameColor">#FFFFFF</Color>
<Color x:Key="BaseLightTextColor">#7b7b7b</Color>
<Color x:Key="OverImageTextColor">#FFFFFF</Color>
<Color x:Key="EcommercePromoTextColor">#FFFFFF</Color>
<Color x:Key="SocialHeaderTextColor">#666666</Color>
<Color x:Key="ArticleHeaderBackgroundColor">#F1F3F5</Color>
<Color x:Key="CustomNavBarTextColor">#FFFFFF</Color>
<Color x:Key="ListViewItemTextColor">#666666</Color>
<Color x:Key="AboutHeaderBackgroundColor">#FFFFFF</Color>
<Color x:Key="BasePageColor">#FFFFFF</Color>
<Color x:Key="BaseTabbedPageColor">#fafafa</Color>
<Color x:Key="MainWrapperBackgroundColor">#EFEFEF</Color>
<Color x:Key="CategoriesListIconColor">#55000000</Color>
<Color x:Key="DashboardIconColor">#FFFFFF</Color>
<!-- COMPLEMENT COLORS -->
<Color x:Key="ComplementColor">#525ABB</Color>
<Color x:Key="TranslucidBlack">#44000000</Color>
<Color x:Key="TranslucidWhite">#22ffffff</Color>
<!-- INDICATOR COLORS -->
<Color x:Key="OkColor">#22c064</Color>
<Color x:Key="ErrorColor">Red</Color>
<Color x:Key="WarningColor">#ffc107</Color>
<Color x:Key="NotificationColor">#1274d1</Color>
<!-- BUTTONS & ENTRY COLORS -->
<Color x:Key="SaveButtonColor">#22c064</Color>
<Color x:Key="DeleteButtonColor">#D50000</Color>
<Color x:Key="LabelButtonColor">#ffffff</Color>
<Color x:Key="PlaceholderColor">#22ffffff</Color>
<Color x:Key="PlaceholderColorEntry">#FFFFFF</Color>
<Color x:Key="RoundedLabelBackgroundColor">#525ABB</Color>
<!-- MAIN MENU COLORS -->
<Color x:Key="MainMenuHeaderBackgroundColor">#384F63</Color>
<Color x:Key="MainMenuBackgroundColor">#F1F3F5</Color>
<Color x:Key="MainMenuSeparatorColor">Transparent</Color>
<Color x:Key="MainMenuTextColor">#666666</Color>
<Color x:Key="MainMenuIconColor">#666666</Color>
<!-- SEPARATORS COLORS -->
<Color x:Key="ListViewSeparatorColor">#D3D3D3</Color>
<Color x:Key="BaseSeparatorColor">#7b7b7b</Color>
<!-- CHAT COLORS -->
<Color x:Key="ChatRightBalloonBackgroundColor">#525ABB</Color>
<Color x:Key="ChatBalloonFooterTextColor">#FFFFFF</Color>
<Color x:Key="ChatRightTextColor">#FFFFFF</Color>
<Color x:Key="ChatLeftTextColor">#FFFFFF</Color>
</ResourceDictionary>
using System;
using System.Collections.Generic;
using Xamarin.Forms;
namespace inutralia
{
public partial class GrialLightTheme
{
public GrialLightTheme()
{
InitializeComponent();
}
}
public partial class GrialLightTheme
{
public GrialLightTheme()
{
InitializeComponent();
}
}
}
......@@ -4,7 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="inutralia.MyAppTheme">
<!--
<!--
THEME COLORS
The colors below will be automatically updated on each platform project by the build task.
......@@ -19,69 +19,63 @@
...but this is:
#FF169CEE
-->
<!-- Grial Theme Exported Colors -->
<Color x:Key="AccentColor">#FFa2c300</Color>
<Color x:Key="BaseTextColor">#666666</Color>
<!-- GENERAL COLORS -->
<Color x:Key="InverseTextColor">White</Color>
<Color x:Key="BrandColor">#ad1457</Color>
<Color x:Key="BrandNameColor">#FFFFFF</Color>
<Color x:Key="BaseLightTextColor">#7b7b7b</Color>
<Color x:Key="OverImageTextColor">#000000</Color>
<Color x:Key="EcommercePromoTextColor">#FFFFFF</Color>
<Color x:Key="SocialHeaderTextColor">#666666</Color>
<Color x:Key="ArticleHeaderBackgroundColor">#F1F3F5</Color>
<Color x:Key="CustomNavBarTextColor">#FFFFFF</Color>
<Color x:Key="ListViewItemTextColor">#666666</Color>
<Color x:Key="AboutHeaderBackgroundColor">#FFFFFF</Color>
<Color x:Key="BasePageColor">#FFFFFF</Color>
<Color x:Key="BaseTabbedPageColor">#fafafa</Color>
<Color x:Key="MainWrapperBackgroundColor">#EFEFEF</Color>
<Color x:Key="CategoriesListIconColor">#55000000</Color>
<Color x:Key="DashboardIconColor">#FFFFFF</Color>
<!-- COMPLEMENT COLORS -->
<Color x:Key="ComplementColor">#d480d6</Color>
<Color x:Key="TranslucidBlack">#44000000</Color>
<Color x:Key="TranslucidWhite">#22ffffff</Color>
<!-- INDICATOR COLORS -->
<Color x:Key="OkColor">#22c064</Color>
<Color x:Key="ErrorColor">Red</Color>
<Color x:Key="WarningColor">#ffc107</Color>
<Color x:Key="NotificationColor">#1274d1</Color>
<!-- BUTTONS & ENTRY COLORS -->
<Color x:Key="SaveButtonColor">#22c064</Color>
<Color x:Key="DeleteButtonColor">#D50000</Color>
<Color x:Key="LabelButtonColor">#ffffff</Color>
<Color x:Key="PlaceholderColor">#22ffffff</Color>
<Color x:Key="PlaceholderColorEntry">#FFFFFF</Color>
<Color x:Key="RoundedLabelBackgroundColor">#525ABB</Color>
<!-- MAIN MENU COLORS -->
<Color x:Key="MainMenuHeaderBackgroundColor">#384F63</Color>
<Color x:Key="MainMenuBackgroundColor">#F1F3F5</Color>
<Color x:Key="MainMenuSeparatorColor">Transparent</Color>
<Color x:Key="MainMenuTextColor">#666666</Color>
<Color x:Key="MainMenuIconColor">#666666</Color>
<!-- SEPARATORS COLORS -->
<Color x:Key="ListViewSeparatorColor">#D3D3D3</Color>
<Color x:Key="BaseSeparatorColor">#7b7b7b</Color>
<!-- CHAT COLORS -->
<Color x:Key="ChatRightBalloonBackgroundColor">#525ABB</Color>
<Color x:Key="ChatBalloonFooterTextColor">#FFFFFF</Color>
<Color x:Key="ChatRightTextColor">#FFFFFF</Color>
<Color x:Key="ChatLeftTextColor">#FFFFFF</Color>
<!-- Grial Theme Exported Colors -->
<Color x:Key="AccentColor">#FFa2c300</Color>
<Color x:Key="BaseTextColor">#666666</Color>
<!-- GENERAL COLORS -->
<Color x:Key="InverseTextColor">White</Color>
<Color x:Key="BrandColor">#ad1457</Color>
<Color x:Key="BrandNameColor">#FFFFFF</Color>
<Color x:Key="BaseLightTextColor">#7b7b7b</Color>
<Color x:Key="OverImageTextColor">#000000</Color>
<Color x:Key="EcommercePromoTextColor">#FFFFFF</Color>
<Color x:Key="SocialHeaderTextColor">#666666</Color>
<Color x:Key="ArticleHeaderBackgroundColor">#F1F3F5</Color>
<Color x:Key="CustomNavBarTextColor">#FFFFFF</Color>
<Color x:Key="ListViewItemTextColor">#666666</Color>
<Color x:Key="AboutHeaderBackgroundColor">#FFFFFF</Color>
<Color x:Key="BasePageColor">#FFFFFF</Color>
<Color x:Key="BaseTabbedPageColor">#fafafa</Color>
<Color x:Key="MainWrapperBackgroundColor">#EFEFEF</Color>
<Color x:Key="CategoriesListIconColor">#55000000</Color>
<Color x:Key="DashboardIconColor">#FFFFFF</Color>
<!-- COMPLEMENT COLORS -->
<Color x:Key="ComplementColor">#d480d6</Color>
<Color x:Key="TranslucidBlack">#44000000</Color>
<Color x:Key="TranslucidWhite">#22ffffff</Color>
<!-- INDICATOR COLORS -->
<Color x:Key="OkColor">#22c064</Color>
<Color x:Key="ErrorColor">Red</Color>
<Color x:Key="WarningColor">#ffc107</Color>
<Color x:Key="NotificationColor">#1274d1</Color>
<!-- BUTTONS & ENTRY COLORS -->
<Color x:Key="SaveButtonColor">#22c064</Color>
<Color x:Key="DeleteButtonColor">#D50000</Color>
<Color x:Key="LabelButtonColor">#ffffff</Color>
<Color x:Key="PlaceholderColor">#22ffffff</Color>
<Color x:Key="PlaceholderColorEntry">#FFFFFF</Color>
<Color x:Key="RoundedLabelBackgroundColor">#525ABB</Color>
<!-- MAIN MENU COLORS -->
<Color x:Key="MainMenuHeaderBackgroundColor">#384F63</Color>
<Color x:Key="MainMenuBackgroundColor">#F1F3F5</Color>
<Color x:Key="MainMenuSeparatorColor">Transparent</Color>
<Color x:Key="MainMenuTextColor">#666666</Color>
<Color x:Key="MainMenuIconColor">#666666</Color>
<!-- SEPARATORS COLORS -->
<Color x:Key="ListViewSeparatorColor">#D3D3D3</Color>
<Color x:Key="BaseSeparatorColor">#7b7b7b</Color>
<!-- CHAT COLORS -->
<Color x:Key="ChatRightBalloonBackgroundColor">#525ABB</Color>
<Color x:Key="ChatBalloonFooterTextColor">#FFFFFF</Color>
<Color x:Key="ChatRightTextColor">#FFFFFF</Color>
<Color x:Key="ChatLeftTextColor">#FFFFFF</Color>
</ResourceDictionary>
using System;
using System.Collections.Generic;
using Xamarin.Forms;
namespace inutralia
{
public partial class MyAppTheme
{
public MyAppTheme()
{
InitializeComponent();
}
}
public partial class MyAppTheme
{
public MyAppTheme()
{
InitializeComponent();
}
}
}
using inutralia.Models;
using System.Threading.Tasks;
using MvvmHelpers; // Este namespace está en el paquete Refractored.MvvmHelpers
using Xamarin.Forms;
namespace inutralia.ViewModels
{
public class ArticleDetailViewModel : ModelBasedViewModel
{
public ArticleDetailViewModel( Article artic) : base (artic)
{
//Title = Generic?.Title;
//Subtitle = Generic?.Body;
}
public class ArticleDetailViewModel : ModelBasedViewModel
{
public ArticleDetailViewModel(Article artic) : base(artic)
{
//Title = Generic?.Title;
//Subtitle = Generic?.Body;
}
public Article Article => Model as Article;
}
}
}
......@@ -2,96 +2,93 @@
using System.Threading.Tasks;
using MvvmHelpers; // Este namespace está en el paquete Refractored.MvvmHelpers
using Xamarin.Forms;
using System.Collections.Generic;
using System.Diagnostics;
namespace inutralia.ViewModels
{
public class ArticleListViewModel : BaseViewModel
{
public ArticleListViewModel()
{
}
public class ArticleListViewModel : BaseViewModel
{
public ArticleListViewModel() { }
// Lista de articulos
ObservableRangeCollection<Article> _Articles;
// Lista de articulos
ObservableRangeCollection<Article> _Articles;
// Comando de update del listadd
Command _RefreshArticlesCommand;
// Comando de update del listadd
Command _RefreshArticlesCommand;
// Acceso a la lista de articulos
public ObservableRangeCollection<Article> Articles
{
// Getter (lazy load), crea la lista si no existe
get { return _Articles ?? (_Articles = new ObservableRangeCollection<Article>()); }
{
// Getter (lazy load), crea la lista si no existe
get { return _Articles ?? (_Articles = new ObservableRangeCollection<Article>()); }
// Setter. cambiar el valor y notifica a la vista de dicho cambio
set
{
_Articles = value;
OnPropertyChanged("Articles");
}
}
// Setter. cambiar el valor y notifica a la vista de dicho cambio
set
{
_Articles = value;
OnPropertyChanged("Articles");
}
}
/// <summary>
/// Método que realiza la carga inicial del listado
/// </summary>
public async Task ExecuteLoadArticlesCommand()
{
// Realiza el proceso de actualización si hay menos de un
// elemento en el listado
if (Articles.Count < 1)
await FetchArticles();
}
/// <summary>
/// Método que realiza la carga inicial del listado
/// </summary>
public async Task ExecuteLoadArticlesCommand()
{
// Realiza el proceso de actualización si hay menos de un
// elemento en el listado
if (Articles.Count < 1)
await FetchArticles();
}
/// <summary>
/// Acceso al comando de actualización del listado
/// </summary>
public Command RefreshArticlesCommand
{
// Getter (lazy load), crea el comando si no existe
get { return _RefreshArticlesCommand ?? (_RefreshArticlesCommand = new Command(async () => await ExecuteRefreshArticlesCommand())); }
}
/// <summary>
/// Acceso al comando de actualización del listado
/// </summary>
public Command RefreshArticlesCommand
{
// Getter (lazy load), crea el comando si no existe
get { return _RefreshArticlesCommand ?? (_RefreshArticlesCommand = new Command(async () => await ExecuteRefreshArticlesCommand())); }
}
/// <summary>
/// Proceso de ejecución del comando de actualización del listado
/// </summary>
async Task ExecuteRefreshArticlesCommand()
{
// Hace que el comando no se pueda ejecutar de nuevo
RefreshArticlesCommand.ChangeCanExecute();
/// <summary>
/// Proceso de ejecución del comando de actualización del listado
/// </summary>
async Task ExecuteRefreshArticlesCommand()
{
// Hace que el comando no se pueda ejecutar de nuevo
RefreshArticlesCommand.ChangeCanExecute();
// Realiza el proceso de actualización
await FetchArticles();
// Realiza el proceso de actualización
await FetchArticles();
// Hace que el comando pueda volver a ejecutarse
RefreshArticlesCommand.ChangeCanExecute();
}
// Hace que el comando pueda volver a ejecutarse
RefreshArticlesCommand.ChangeCanExecute();
}
/// <summary>
/// Proceso de actualización del listado
/// </summary>
async Task FetchArticles()
{
// Indicamos que estamos ocupados (provoca que aparezca el indicador de carga)
IsBusy = true;
/// <summary>
/// Proceso de actualización del listado
/// </summary>
async Task FetchArticles()
{
// Indicamos que estamos 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)
// Nota: Al obtener el listado, el controlador Rest del servidor no retorna el cuerpo de
// la notificación (campo Body)
try
{
Articles = new ObservableRangeCollection<Article>(await App.API.RefreshListAsync<Article>());
}
catch (System.Exception e)
{
// Llamada al API para coger el listado (provoca que se actualize la vista del listado)
// Nota: Al obtener el listado, el controlador Rest del servidor no retorna el cuerpo de
// la notificación (campo Body)
try
{
Articles = new ObservableRangeCollection<Article>(await App.API.RefreshListAsync<Article>());
}
catch (System.Exception e)
{
Debug.WriteLine(e.Message);
Articles.Clear();
}
Articles.Clear();
}
// Indicamos que ya no estamos ocupados (provoca que desaparezca el indicador de carga)
IsBusy = false;
}
}
// Indicamos que ya no estamos ocupados (provoca que desaparezca el indicador de carga)
IsBusy = false;
}
}
}
\ No newline at end of file
......@@ -5,12 +5,12 @@ using System.Collections.Generic;
namespace inutralia
{
/// <summary>
/// Implements the INavigation interface on top of BaseViewModel.
/// </summary>
public abstract class BaseNavigationViewModel : BaseViewModel, INavigation
{
INavigation _Navigation
/// <summary>
/// Implements the INavigation interface on top of BaseViewModel.
/// </summary>
public abstract class BaseNavigationViewModel : BaseViewModel, INavigation
{
INavigation _Navigation
{
get
{
......@@ -21,91 +21,91 @@ namespace inutralia
return mainPage?.Navigation;
}
}
#region INavigation implementation
public void RemovePage(Page page)
{
_Navigation?.RemovePage(page);
}
public void InsertPageBefore(Page page, Page before)
{
_Navigation?.InsertPageBefore(page, before);
}
public async Task PushAsync(Page page)
{
var task = _Navigation?.PushAsync(page);
if (task != null)
await task;
}
public async Task<Page> PopAsync()
{
var task = _Navigation?.PopAsync();
return task != null ? await task : await Task.FromResult(null as Page);
}
public async Task PopToRootAsync()
{
var task = _Navigation?.PopToRootAsync();
if (task != null)
await task;
}
public async Task PushModalAsync(Page page)
{
var task = _Navigation?.PushModalAsync(page);
if (task != null)
await task;
}
public async Task<Page> PopModalAsync()
{
var task = _Navigation?.PopModalAsync();
return task != null ? await task : await Task.FromResult(null as Page);
}
public async Task PushAsync(Page page, bool animated)
{
var task = _Navigation?.PushAsync(page, animated);
if (task != null)
await task;
}
public async Task<Page> PopAsync(bool animated)
{
var task = _Navigation?.PopAsync(animated);
return task != null ? await task : await Task.FromResult(null as Page);
}
public async Task PopToRootAsync(bool animated)
{
var task = _Navigation?.PopToRootAsync(animated);
if (task != null)
await task;
}
public async Task PushModalAsync(Page page, bool animated)
{
var task = _Navigation?.PushModalAsync(page, animated);
if (task != null)
await task;
}
public async Task<Page> PopModalAsync(bool animated)
{
var task = _Navigation?.PopModalAsync(animated);
return task != null ? await task : await Task.FromResult(null as Page);
}
public IReadOnlyList<Page> NavigationStack => _Navigation?.NavigationStack;
public IReadOnlyList<Page> ModalStack => _Navigation?.ModalStack;
#endregion
}
#region INavigation implementation
public void RemovePage(Page page)
{
_Navigation?.RemovePage(page);
}
public void InsertPageBefore(Page page, Page before)
{
_Navigation?.InsertPageBefore(page, before);
}
public async Task PushAsync(Page page)
{
var task = _Navigation?.PushAsync(page);
if (task != null)
await task;
}
public async Task<Page> PopAsync()
{
var task = _Navigation?.PopAsync();
return task != null ? await task : await Task.FromResult(null as Page);
}
public async Task PopToRootAsync()
{
var task = _Navigation?.PopToRootAsync();
if (task != null)
await task;
}
public async Task PushModalAsync(Page page)
{
var task = _Navigation?.PushModalAsync(page);
if (task != null)
await task;
}
public async Task<Page> PopModalAsync()
{
var task = _Navigation?.PopModalAsync();
return task != null ? await task : await Task.FromResult(null as Page);
}
public async Task PushAsync(Page page, bool animated)
{
var task = _Navigation?.PushAsync(page, animated);
if (task != null)
await task;
}
public async Task<Page> PopAsync(bool animated)
{
var task = _Navigation?.PopAsync(animated);
return task != null ? await task : await Task.FromResult(null as Page);
}
public async Task PopToRootAsync(bool animated)
{
var task = _Navigation?.PopToRootAsync(animated);
if (task != null)
await task;
}
public async Task PushModalAsync(Page page, bool animated)
{
var task = _Navigation?.PushModalAsync(page, animated);
if (task != null)
await task;
}
public async Task<Page> PopModalAsync(bool animated)
{
var task = _Navigation?.PopModalAsync(animated);
return task != null ? await task : await Task.FromResult(null as Page);
}
public IReadOnlyList<Page> NavigationStack => _Navigation?.NavigationStack;
public IReadOnlyList<Page> ModalStack => _Navigation?.ModalStack;
#endregion
}
}
......@@ -8,13 +8,9 @@ namespace inutralia.ViewModels
{
public class CustomMenuViewModel : MenuBaseViewModel
{
public CustomMenuViewModel() : this(new Models.Menu())
{
}
public CustomMenuViewModel() : this(new Models.Menu()) { }
public CustomMenuViewModel(Models.Menu menu) : base(menu)
{
}
public CustomMenuViewModel(Models.Menu menu) : base(menu) { }
/// <summary>
/// El menú guardado en el almacenamiento local
......@@ -295,7 +291,6 @@ namespace inutralia.ViewModels
_SelectionHasBeenChanged = false;
IsBusy = false;
OnPropertyChanged("NoMenuPanel");
}
protected void SelectionChanged()
......@@ -361,7 +356,7 @@ namespace inutralia.ViewModels
}
//protected void AddRecipe ( HashSet<string> ingredients, IList<Recipe> recipes, int index)
protected void AddRecipe(HashSet<Ingredient> ingredients, IList<Recipe> recipes, int index)
protected async void AddRecipe(HashSet<Ingredient> ingredients, IList<Recipe> recipes, int index)
{
if ((index >= 0) && (index < recipes.Count))
{
......@@ -375,7 +370,8 @@ namespace inutralia.ViewModels
ingredients.Add(new Ingredient() { Name = ing.Name, Id = ing.Id });
} //endforeach
} //endif
} //endif
}//endif
await App.LocalData.RefreshListAsync<ShoppingList>();
}
protected override void OnDataRefreshed()
......
using inutralia.Models;
using System.Threading.Tasks;
using MvvmHelpers; // Este namespace está en el paquete Refractored.MvvmHelpers
using Xamarin.Forms;
using System;
namespace inutralia.ViewModels
{
public class GenericDetailViewModel : MenuBaseViewModel
{
public GenericDetailViewModel(Generic gener) : base (gener)
{
}
public class GenericDetailViewModel : MenuBaseViewModel
{
public GenericDetailViewModel(Generic gener) : base(gener) { }
}
}
......@@ -5,91 +5,89 @@ using Xamarin.Forms;
namespace inutralia.ViewModels
{
public class GenericListViewModel : BaseViewModel
{
public GenericListViewModel()
{
}
public class GenericListViewModel : BaseViewModel
{
public GenericListViewModel() { }
//Lista de menús genéricos
ObservableRangeCollection<Generic> _Generics;
//Lista de menús genéricos
ObservableRangeCollection<Generic> _Generics;
// Comando de update del listado
Command _RefreshGenericsCommand;
// Comando de update del listado
Command _RefreshGenericsCommand;
// Acceso a la lista de menús genéricos
public ObservableRangeCollection<Generic> Generics
{
// Getter (lazy load), crea la lista si no existe
get { return _Generics ?? (_Generics = new ObservableRangeCollection<Generic>()); }
// Acceso a la lista de menús genéricos
public ObservableRangeCollection<Generic> Generics
{
// Getter (lazy load), crea la lista si no existe
get { return _Generics ?? (_Generics = new ObservableRangeCollection<Generic>()); }
// Setter. Cambia el valor y notifica a la vista de dicho cambio
set
{
_Generics = value;
OnPropertyChanged("Generics");
}
}
// Setter. Cambia el valor y notifica a la vista de dicho cambio
set
{
_Generics = value;
OnPropertyChanged("Generics");
}
}
/// <summary>
/// Método que realiza la carga inicial del listado
/// </summary>
public async Task ExecuteLoadGenericsCommand()
{
// Realiza el proceso de actualización si hay menos de un
// elemento en el listado
if (Generics.Count < 1)
await FetchGenerics();
}
{
// Realiza el proceso de actualización si hay menos de un
// elemento en el listado
if (Generics.Count < 1)
await FetchGenerics();
}
/// <summary>
/// Acceso al comando de actualización del listado
/// </summary>
public Command RefreshGenericsCommand
{
// Getter (lazy load), crea el comando si no existe
get { return _RefreshGenericsCommand ?? (_RefreshGenericsCommand = new Command(async () => await ExecuteRefreshGenericsCommand())); }
}
/// <summary>
/// Acceso al comando de actualización del listado
/// </summary>
public Command RefreshGenericsCommand
{
// Getter (lazy load), crea el comando si no existe
get { return _RefreshGenericsCommand ?? (_RefreshGenericsCommand = new Command(async () => await ExecuteRefreshGenericsCommand())); }
}
/// <summary>
/// Proceso de ejecución del comando de actualización del listado
/// </summary>
async Task ExecuteRefreshGenericsCommand()
{
// Hace que el comando no se pueda ejecutar de nuevo
RefreshGenericsCommand.ChangeCanExecute();
/// <summary>
/// Proceso de ejecución del comando de actualización del listado
/// </summary>
async Task ExecuteRefreshGenericsCommand()
{
// Hace que el comando no se pueda ejecutar de nuevo
RefreshGenericsCommand.ChangeCanExecute();
// Realiza el proceso de actualización
await FetchGenerics();
// Realiza el proceso de actualización
await FetchGenerics();
// Hace que el comando pueda volver a ejecutarse
RefreshGenericsCommand.ChangeCanExecute();
}
// Hace que el comando pueda volver a ejecutarse
RefreshGenericsCommand.ChangeCanExecute();
}
/// <summary>
/// Proceso de actualización del listado
/// </summary>
async Task FetchGenerics()
{
// Indicamos que estamos ocupados (provoca que aparezca el indicador de carga)
IsBusy = true;
/// <summary>
/// Proceso de actualización del listado
/// </summary>
async Task FetchGenerics()
{
// Indicamos que estamos 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)
// Nota: Al obtener el listado, el controlador Rest del servidor no retorna el cuerpo de
// la notificación (campo Body)
try
{
Generics = new ObservableRangeCollection<Generic>(await App.API.RefreshListAsync<Generic>());
}
catch (System.Exception)
{
// Llamada al API para coger el listado (provoca que se actualize la vista del listado)
// Nota: Al obtener el listado, el controlador Rest del servidor no retorna el cuerpo de
// la notificación (campo Body)
try
{
Generics = new ObservableRangeCollection<Generic>(await App.API.RefreshListAsync<Generic>());
}
catch (System.Exception)
{
Generics.Clear();
}
Generics.Clear();
}
// Indicamos que ya no estamos ocupados (provoca que desaparezca el indicador de carga)
IsBusy = false;
}
}
// Indicamos que ya no estamos ocupados (provoca que desaparezca el indicador de carga)
IsBusy = false;
}
}
}
\ No newline at end of file
using inutralia.Models;
using inutralia.Views;
using System.Threading.Tasks;
using MvvmHelpers; // Este namespace está en el paquete Refractored.MvvmHelpers
using Xamarin.Forms;
using System;
......@@ -10,12 +9,13 @@ namespace inutralia.ViewModels
/// <summary>
/// ViewModel de un menú semanal
/// </summary>
public abstract class MenuBaseViewModel : ModelBasedViewModel
{
public MenuBaseViewModel ( MenuBase menu) : base (menu)
{
public abstract class MenuBaseViewModel : ModelBasedViewModel
{
public MenuBaseViewModel(MenuBase menu) : base(menu)
{
Title = WeekMenu?.Title;
}
}
#region Properties
......@@ -37,13 +37,13 @@ namespace inutralia.ViewModels
get { return _Index; }
set
{
if( (_Index != value) && (value >= 0) && (value < WeekMenu?.Days?.Count) )
if ((_Index != value) && (value >= 0) && (value < WeekMenu?.Days?.Count))
{
_Index = value;
OnPropertyChanged ("Index");
OnPropertyChanged ("CurrentDay");
OnPropertyChanged("Index");
OnPropertyChanged("CurrentDay");
OnIndexChanged ();
OnIndexChanged();
} //endif
}
}
......@@ -55,7 +55,7 @@ namespace inutralia.ViewModels
{
get
{
return ( (Index >= 0) && (Index < WeekMenu?.Days?.Count) ) ? WeekMenu.Days [Index] : null;
return ((Index >= 0) && (Index < WeekMenu?.Days?.Count)) ? WeekMenu.Days[Index] : null;
}
}
......@@ -69,8 +69,8 @@ namespace inutralia.ViewModels
get { return _LoadingRecipes; }
set
{
SetProperty (ref _LoadingRecipes, value, "IsLoadingRecipes");
OnPropertyChanged ("IsNotLoadingRecipes");
SetProperty(ref _LoadingRecipes, value, "IsLoadingRecipes");
OnPropertyChanged("IsNotLoadingRecipes");
}
}
......@@ -82,8 +82,8 @@ namespace inutralia.ViewModels
get { return !_LoadingRecipes; }
set
{
SetProperty (ref _LoadingRecipes, !value, "IsLoadingRecipes");
OnPropertyChanged ("IsNotLoadingRecipes");
SetProperty(ref _LoadingRecipes, !value, "IsLoadingRecipes");
OnPropertyChanged("IsNotLoadingRecipes");
}
}
......@@ -96,8 +96,8 @@ namespace inutralia.ViewModels
/// <summary>
/// Comando para mostrar una receta
/// </summary>
public Command ShowRecipeCommand => _ShowRecipeCommand ??
(_ShowRecipeCommand = new Command (async (parameter) => await ShowRecipe (parameter as Recipe)));
public Command ShowRecipeCommand => _ShowRecipeCommand ??
(_ShowRecipeCommand = new Command(async (parameter) => await ShowRecipe(parameter as Recipe)));
protected Command _ShowRecomendationCommand = null;
......@@ -105,7 +105,7 @@ namespace inutralia.ViewModels
/// Comando para mostrar las recomendaciones
/// </summary>
public Command ShowRecomendationCommand => _ShowRecomendationCommand ??
(_ShowRecomendationCommand = new Command (async () => await ShowRecomendation()));
(_ShowRecomendationCommand = new Command(async () => await ShowRecomendation()));
#endregion
......@@ -114,7 +114,7 @@ namespace inutralia.ViewModels
/// <summary>
/// Actualiza los datos de todas las recetas
/// </summary>
public async Task LoadAllRecipesAsync ()
public async Task LoadAllRecipesAsync()
{
IsLoadingRecipes = true;
......@@ -122,13 +122,13 @@ namespace inutralia.ViewModels
foreach (var d in WeekMenu.Days)
{
foreach (var r in d.LunchFirst)
await App.API.RefreshItemAsync (r);
await App.API.RefreshItemAsync(r);
foreach (var r in d.LunchSecond)
await App.API.RefreshItemAsync (r);
await App.API.RefreshItemAsync(r);
foreach (var r in d.DinnerFirst)
await App.API.RefreshItemAsync (r);
await App.API.RefreshItemAsync(r);
foreach (var r in d.DinnerSecond)
await App.API.RefreshItemAsync (r);
await App.API.RefreshItemAsync(r);
} //endforeach
IsLoadingRecipes = false;
......@@ -140,15 +140,15 @@ namespace inutralia.ViewModels
/// <param name="recipe">La receta a mostrar</param>
protected async Task ShowRecipe(Recipe recipe)
{
await PushAsync (new RecipeDetailView () { BindingContext = new RecipeViewModel(recipe) });
await PushAsync(new RecipeDetailView() { BindingContext = new RecipeViewModel(recipe) });
}
/// <summary>
/// Navega a la vista de recomendaciones
/// </summary>
protected async Task ShowRecomendation ()
protected async Task ShowRecomendation()
{
await PushAsync (new RecomendationView () { BindingContext = WeekMenu });
await PushAsync(new RecomendationView() { BindingContext = WeekMenu });
}
#endregion
......@@ -156,12 +156,12 @@ namespace inutralia.ViewModels
/// <summary>
/// Llamado cuando se han actualizado los datos
/// </summary>
protected override void OnDataRefreshed ()
protected override void OnDataRefreshed()
{
base.OnDataRefreshed ();
base.OnDataRefreshed();
// Informar que ha cambiado el menú
OnPropertyChanged ("WeekMenu");
OnPropertyChanged("WeekMenu");
// Cambiar título
Title = WeekMenu?.Title;
......@@ -173,19 +173,17 @@ namespace inutralia.ViewModels
DayOfWeek dw = DateTime.Now.DayOfWeek;
// Como DayOfWeek empieza con el 0 en Domingo, le "restamos 1 modulo 7"
Index = ( (int) dw + 6) % 7;
Index = ((int)dw + 6) % 7;
} //endif
// Informar que ha cambiado el día actual (aunque no cambie el índice
// puede haber cambiado el contenido)
OnPropertyChanged ("CurrentDay");
OnPropertyChanged("CurrentDay");
}
/// <summary>
/// Llamado cuando ha cambiado el índice del día seleccionado
/// </summary>
protected virtual void OnIndexChanged ()
{
}
protected virtual void OnIndexChanged() { }
}
}
......@@ -12,12 +12,10 @@ namespace inutralia.ViewModels
public RecipeListViewModel()
{
Title = "Recetas";
Filters = new RecipeListOptionsViewModel();
}
public RecipeListOptionsViewModel Filters
{ get; private set; }
public RecipeListOptionsViewModel Filters { get; private set; }
// Lista de articulos
ObservableRangeCollection<Recipe> _Recipes;
......@@ -36,13 +34,13 @@ namespace inutralia.ViewModels
{
_Recipes = value;
OnPropertyChanged("Recipes");
}
}
// Indica si hay resultados
public bool IsEmpty => IsNotBusy && (Recipes.Count < 1);
public bool IsNotEmpty => IsNotBusy && (Recipes.Count > 0);
/// <summary>
/// Método que realiza la carga inicial del listado
/// </summary>
......@@ -106,31 +104,31 @@ namespace inutralia.ViewModels
{
if (orFlags.Length > 0)
orFlags += ",";
orFlags += cat.Id.ToString ();
orFlags += cat.Id.ToString();
}
else
{
if (flags.Length > 0)
flags += ",";
flags += cat.Id.ToString ();
flags += cat.Id.ToString();
} //endif
} //endif
} //endforeach
} //endforeach
if (string.IsNullOrEmpty (flags) && string.IsNullOrEmpty (orFlags) && string.IsNullOrEmpty(Filters?.Desc) )
if (string.IsNullOrEmpty(flags) && string.IsNullOrEmpty(orFlags) && string.IsNullOrEmpty(Filters?.Desc))
{
Recipes = new ObservableRangeCollection<Recipe> (await App.API.RefreshListAsync<Recipe> ());
Recipes = new ObservableRangeCollection<Recipe>(await App.API.RefreshListAsync<Recipe>());
}
else
{
var options = new Dictionary<string, string> ();
if (!string.IsNullOrEmpty (flags)) options.Add ("flags", flags);
if (!string.IsNullOrEmpty (orFlags)) options.Add ("flags_or", orFlags);
if (!string.IsNullOrEmpty (Filters?.Desc)) options.Add ("desc", Filters.Desc);
var options = new Dictionary<string, string>();
if (!string.IsNullOrEmpty(flags)) options.Add("flags", flags);
if (!string.IsNullOrEmpty(orFlags)) options.Add("flags_or", orFlags);
if (!string.IsNullOrEmpty(Filters?.Desc)) options.Add("desc", Filters.Desc);
var recipes = await App.API.RawMessage<List<Recipe>> (HttpMethod.Post, "recipes", options);
Recipes = new ObservableRangeCollection<Recipe> (recipes);
var recipes = await App.API.RawMessage<List<Recipe>>(HttpMethod.Post, "recipes", options);
Recipes = new ObservableRangeCollection<Recipe>(recipes);
} //endif
}
catch (System.Exception e)
......@@ -143,6 +141,5 @@ namespace inutralia.ViewModels
OnPropertyChanged("IsEmpty");
OnPropertyChanged("IsNotEmpty");
}
}
}
using inutralia.Models;
using MvvmHelpers;
using System.Threading.Tasks;
namespace inutralia.ViewModels
{
public class RecipeViewModel : BaseNavigationViewModel
{
public RecipeViewModel ( Recipe recipe)
public RecipeViewModel(Recipe recipe)
{
Recipe = recipe;
Title = Recipe.Name;
if(Recipe.Ingredients == null)
if (Recipe.Ingredients == null)
Recipe.Ingredients = new Ingredient[0];
}
public Recipe Recipe { get; private set; }
public async Task RefreshData ()
public async Task RefreshData()
{
if (Recipe == null)
return;
IsBusy = true;
if (await App.API.RefreshItemAsync (Recipe))
if (await App.API.RefreshItemAsync(Recipe))
{
OnPropertyChanged ("Recipe");
OnPropertyChanged("Recipe");
// Cambiar título
Title = Recipe.Name;
......@@ -33,6 +32,5 @@ namespace inutralia.ViewModels
IsBusy = false;
}
}
}
using inutralia.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace inutralia.ViewModels
......@@ -12,7 +8,7 @@ namespace inutralia.ViewModels
/// </summary>
public abstract class ModelBasedViewModel : BaseNavigationViewModel
{
public ModelBasedViewModel ( ObservableEntityData model)
public ModelBasedViewModel(ObservableEntityData model)
{
Model = model;
}
......@@ -25,20 +21,20 @@ namespace inutralia.ViewModels
/// <summary>
/// Refresca los datos del modelo asociado
/// </summary>
public async Task RefreshData ()
public async Task RefreshData()
{
if (Model == null)
return;
IsBusy = true;
if (await App.API.RefreshItemAsync (Model))
if (await App.API.RefreshItemAsync(Model))
{
// Informar que el modelo ha cambiado
OnPropertyChanged ("Model");
OnPropertyChanged("Model");
// Comportamiento específico de clases hijas
OnDataRefreshed ();
OnDataRefreshed();
} //endif
IsBusy = false;
......@@ -47,9 +43,6 @@ namespace inutralia.ViewModels
/// <summary>
/// Permite a las clases hijas realizar acciones específicas
/// </summary>
protected virtual void OnDataRefreshed ()
{
}
protected virtual void OnDataRefreshed() { }
}
}
using inutralia.Models;
using System.Threading.Tasks;
using MvvmHelpers; // Este namespace está en el paquete Refractored.MvvmHelpers
using Xamarin.Forms;
using System;
namespace inutralia.ViewModels
{
public class ProfileViewModel : BaseNavigationViewModel
{
public ProfileViewModel()
{
Profile = new Profile();
}
public class ProfileViewModel : BaseNavigationViewModel
{
public ProfileViewModel() { Profile = new Profile(); }
public Profile Profile { private set; get;}
public Profile Profile { private set; get; }
public string Code => Profile?.Code;
public int Gender
{
get
{
return Profile.Gender == 'H' ? 0 : 1;
}
set
{
Profile.Gender = value == 0 ?'H':'M';
}
get { return Profile.Gender == 'H' ? 0 : 1; }
set { Profile.Gender = value == 0 ? 'H' : 'M'; }
}
public int Physical
{
get
{
return Profile.Physical > 0 ? (Profile.Physical -1) : 0;
}
set
{
Profile.Physical = value + 1;
}
get { return Profile.Physical > 0 ? (Profile.Physical - 1) : 0; }
set { Profile.Physical = value + 1; }
}
public int Preference
{
get
{
return Profile.Preference -1 ;
}
set
{
Profile.Preference = value + 1;
}
get { return Profile.Preference - 1; }
set { Profile.Preference = value + 1; }
}
public async Task RefreshData()
{
IsBusy = true;
{
IsBusy = true;
if (await App.API.RefreshItemAsync(Profile))
{
if (await App.API.RefreshItemAsync(Profile))
{
OnPropertyChanged("Preference");
OnPropertyChanged("Profile");
OnPropertyChanged("Profile");
OnPropertyChanged("Physical");
OnPropertyChanged("Gender");
}
IsBusy = false;
}
public async Task saveData()
{
IsBusy = true;
IsBusy = false;
}
public async Task saveData()
{
IsBusy = true;
await App.API.UpdateItemAsync(Profile);
IsBusy = false;
}
}
IsBusy = false;
}
}
}
using inutralia.Models;
using MvvmHelpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using MvvmHelpers;
namespace inutralia.ViewModels
{
public class RecipeListOptionsViewModel : BaseNavigationViewModel
{
public RecipeListOptionsViewModel ()
{
Title = "Filtrado de Recetas";
}
public RecipeListOptionsViewModel() { Title = "Filtrado de Recetas"; }
public string Desc { get; set; }
......@@ -22,29 +12,26 @@ namespace inutralia.ViewModels
public ObservableRangeCollection<RecipeOptionGroupViewModel> Groups
{
get { return _Groups ?? (_Groups = new ObservableRangeCollection<RecipeOptionGroupViewModel> ()); }
get { return _Groups ?? (_Groups = new ObservableRangeCollection<RecipeOptionGroupViewModel>()); }
set
{
SetProperty (ref _Groups, value);
}
set { SetProperty(ref _Groups, value); }
}
/// <summary>
/// Método que realiza la carga inicial de las opciones de filtrado
/// </summary>
public async Task ExecuteLoadOptionsCommand ()
public void ExecuteLoadOptionsCommand()
{
// Realiza el proceso de actualización si hay menos de un
// elemento en el listado
if (Groups.Count < 1)
await FetchOptions ();
FetchOptions();
}
/// <summary>
/// Proceso de actualización del listado
/// </summary>
async Task FetchOptions ()
void FetchOptions()
{
// Indicamos que estamos ocupados (provoca que aparezca el indicador de carga)
IsBusy = true;
......@@ -55,21 +42,18 @@ namespace inutralia.ViewModels
try
{
var groups = App.FilterOptions;
var groupList = new ObservableRangeCollection<RecipeOptionGroupViewModel> ();
var groupList = new ObservableRangeCollection<RecipeOptionGroupViewModel>();
foreach (var group in groups)
groupList.Add (new RecipeOptionGroupViewModel (group));
groupList.Add(new RecipeOptionGroupViewModel(group));
Groups = groupList;
}
catch (System.Exception e)
{
Groups.Clear ();
Groups.Clear();
}
// Indicamos que ya no estamos ocupados (provoca que desaparezca el indicador de carga)
IsBusy = false;
}
}
}
......@@ -9,11 +9,11 @@ namespace inutralia.ViewModels
public RecipeOptionGroup Group { get; private set; }
public RecipeOptionGroupViewModel ( RecipeOptionGroup group)
public RecipeOptionGroupViewModel(RecipeOptionGroup group)
{
Name = group.Name;
Group = group;
AddRange (group.Options);
AddRange(group.Options);
}
}
}
using inutralia.Models;
using MvvmHelpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
......@@ -11,10 +7,7 @@ namespace inutralia.ViewModels
{
public class ShoppingListViewModel : BaseNavigationViewModel
{
public ShoppingListViewModel()
{
}
public ShoppingListViewModel() { }
ObservableRangeCollection<ShoppingList> _ShoppingList;
......@@ -38,36 +31,36 @@ namespace inutralia.ViewModels
}
}
public async Task AddItem (ShoppingList item)
public async Task AddItem(ShoppingList item)
{
// Añadir elemento y refrescar lista
if (await App.LocalData.UpdateItemAsync (item, true) != null)
await FetchShoppingList ();
if (await App.LocalData.UpdateItemAsync(item, true) != null)
await FetchShoppingList();
}
public async Task DeleteSelected ()
public async Task DeleteSelected()
{
IsBusy = true;
foreach (var item in ShoppingList)
if(item.Select)
await App.LocalData.DeleteItemAsync (item);
if (item.Select)
await App.LocalData.DeleteItemAsync(item);
ShoppingList.Clear ();
ShoppingList.Clear();
await FetchShoppingList ();
await FetchShoppingList();
}
public async Task DeleteAll ()
public async Task DeleteAll()
{
IsBusy = true;
foreach (var item in ShoppingList)
await App.LocalData.DeleteItemAsync (item);
await App.LocalData.DeleteItemAsync(item);
ShoppingList.Clear ();
ShoppingList.Clear();
await FetchShoppingList ();
await FetchShoppingList();
}
/// <summary>
......@@ -121,10 +114,10 @@ namespace inutralia.ViewModels
try
{
// Obtener lista
var list = await App.LocalData.RefreshListAsync<ShoppingList> ();
var list = await App.LocalData.RefreshListAsync<ShoppingList>();
// Ordenarla
list.Sort ((a, b) => { return a.Text.CompareTo (b.Text); });
list.Sort((a, b) => { return a.Text.CompareTo(b.Text); });
// Asignarla a la que utiliza la vista
ShoppingList = new ObservableRangeCollection<ShoppingList>(list);
......@@ -138,7 +131,6 @@ namespace inutralia.ViewModels
IsBusy = false;
}
public Command DeleteShoppingListCommand
{
// Getter (lazy load), crea el comando si no existe. Nótese que, a diferencia del comando
......@@ -173,6 +165,6 @@ namespace inutralia.ViewModels
// Indicamos que ya no estamos ocupados
IsBusy = false;
} //endif
}
}
}
}
using inutralia.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace inutralia.ViewModels
......@@ -13,9 +10,9 @@ namespace inutralia.ViewModels
{
public TrivialQuestion Question { get; set; }
public string ValidAnswer => Question.Options [Question.ValidIndex];
public string ValidAnswer => Question.Options[Question.ValidIndex];
public string Answer => Question.Options [SelectedAnswer];
public string Answer => Question.Options[SelectedAnswer];
public int SelectedAnswer { get; set; }
......@@ -28,8 +25,8 @@ namespace inutralia.ViewModels
public List<QuestionResult> Results { get; private set; }
public bool IsComplete =>
(Game?.Questions?.Count > 0) &&
public bool IsComplete =>
(Game?.Questions?.Count > 0) &&
(Game?.Questions?.Count == Game?.Answers?.Count);
public bool IsNotComplete => !IsComplete;
......@@ -39,45 +36,45 @@ namespace inutralia.ViewModels
get
{
int n = Game.Answers.Count;
return (n >= 0) && (n < Game.Questions.Count) ? Game.Questions [n] : null;
return (n >= 0) && (n < Game.Questions.Count) ? Game.Questions[n] : null;
}
}
public TrivialGameViewModel ( TrivialGame game)
public TrivialGameViewModel(TrivialGame game)
{
Game = game;
Results = null;
GenerateTitle ();
GenerateResults ();
GenerateTitle();
GenerateResults();
}
public async Task<bool> Answer ( int answer)
public async Task<bool> Answer(int answer)
{
bool retVal = Game.Answer (answer);
bool retVal = Game.Answer(answer);
await App.LocalData.UpdateItemAsync (Game);
await App.LocalData.UpdateItemAsync(Game);
GenerateTitle ();
GenerateResults ();
OnPropertyChanged ("CurrentQuestion");
OnPropertyChanged ("IsComplete");
OnPropertyChanged ("IsNotComplete");
GenerateTitle();
GenerateResults();
OnPropertyChanged("CurrentQuestion");
OnPropertyChanged("IsComplete");
OnPropertyChanged("IsNotComplete");
return retVal;
}
protected void GenerateResults ()
protected void GenerateResults()
{
if(IsComplete)
if (IsComplete)
{
if(Results == null)
if (Results == null)
{
Results = new List<QuestionResult> ();
for(int i = 0; i < Game.Questions.Count; i++)
Results = new List<QuestionResult>();
for (int i = 0; i < Game.Questions.Count; i++)
{
TrivialQuestion q = Game.Questions [i];
int answer = Game.Answers [i];
Results.Add (new QuestionResult ()
TrivialQuestion q = Game.Questions[i];
int answer = Game.Answers[i];
Results.Add(new QuestionResult()
{
Question = q,
SelectedAnswer = answer,
......@@ -85,14 +82,14 @@ namespace inutralia.ViewModels
});
} //endfor
OnPropertyChanged ("Results");
OnPropertyChanged("Results");
} //endif
} //endif
}
protected void GenerateTitle ()
protected void GenerateTitle()
{
if(IsComplete)
if (IsComplete)
{
Title = "Trivial: Partida completada";
}
......@@ -101,6 +98,5 @@ namespace inutralia.ViewModels
Title = $"Trivial: Pregunta {Game.Answers.Count + 1} de {Game.Questions.Count}";
} //endif
}
}
}
......@@ -3,8 +3,6 @@ using inutralia.Views;
using MvvmHelpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
......@@ -12,9 +10,7 @@ namespace inutralia.ViewModels
{
public class TrivialListViewModel : BaseNavigationViewModel
{
public TrivialListViewModel ()
{
}
public TrivialListViewModel() { }
// Lista de partidas
ObservableRangeCollection<TrivialGame> _Games;
......@@ -23,13 +19,13 @@ namespace inutralia.ViewModels
public ObservableRangeCollection<TrivialGame> Games
{
// Getter (lazy load), crea la lista si no existe
get { return _Games ?? (_Games = new ObservableRangeCollection<TrivialGame> ()); }
get { return _Games ?? (_Games = new ObservableRangeCollection<TrivialGame>()); }
// Setter. cambiar el valor y notifica a la vista de dicho cambio
set
{
_Games = value;
OnPropertyChanged ("Games");
OnPropertyChanged("Games");
}
}
......@@ -37,24 +33,21 @@ namespace inutralia.ViewModels
Command _NewGameCommand;
public Command NewGameCommand =>
_NewGameCommand ?? (_NewGameCommand = new Command(async () => await ExecuteNewGameCommand ()));
public Command NewGameCommand => _NewGameCommand ?? (_NewGameCommand = new Command(async () => await ExecuteNewGameCommand()));
protected async Task ExecuteNewGameCommand ()
protected async Task ExecuteNewGameCommand()
{
NewGameCommand.ChangeCanExecute ();
NewGameCommand.ChangeCanExecute();
List<TrivialQuestion> questions = null;
try
{
questions = await App.API.RefreshListAsync<TrivialQuestion> ();
questions = await App.API.RefreshListAsync<TrivialQuestion>();
}
catch (Exception e)
{ }
catch (Exception e) { }
if (questions == null)
questions = new List<TrivialQuestion> ()
if (questions == null) questions = new List<TrivialQuestion>()
{
new TrivialQuestion ()
{
......@@ -66,16 +59,15 @@ namespace inutralia.ViewModels
}
};
var game = TrivialGame.Create (questions);
await App.LocalData.UpdateItemAsync (game, true);
var game = TrivialGame.Create(questions);
await App.LocalData.UpdateItemAsync(game, true);
await PushAsync (new TrivialGameView ()
await PushAsync(new TrivialGameView()
{
BindingContext = new TrivialGameViewModel (game)
BindingContext = new TrivialGameViewModel(game)
});
NewGameCommand.ChangeCanExecute ();
NewGameCommand.ChangeCanExecute();
}
#endregion
......@@ -85,9 +77,9 @@ namespace inutralia.ViewModels
Command _DeleteGameCommand;
public Command DeleteGameCommand =>
_DeleteGameCommand ?? (_DeleteGameCommand = new Command (async (parameter) => await ExecuteDeleteGameCommand (parameter as TrivialGame)));
_DeleteGameCommand ?? (_DeleteGameCommand = new Command(async (parameter) => await ExecuteDeleteGameCommand(parameter as TrivialGame)));
protected async Task ExecuteDeleteGameCommand (TrivialGame game)
protected async Task ExecuteDeleteGameCommand(TrivialGame game)
{
// Verificar parámetro
if (game != null)
......@@ -96,10 +88,10 @@ namespace inutralia.ViewModels
IsBusy = true;
// Llamamos al API para borrar la notificación
await App.LocalData.DeleteItemAsync (game);
await App.LocalData.DeleteItemAsync(game);
// Actualizamos la lista
Games.Remove (game);
Games.Remove(game);
// Indicamos que ya no estamos ocupados (provoca que desaparezca el indicador de carga)
IsBusy = false;
......@@ -112,15 +104,15 @@ namespace inutralia.ViewModels
/// <summary>
/// Método que realiza la carga inicial del listado
/// </summary>
public async Task RefreshList ()
public async Task RefreshList()
{
await FetchGames ();
await FetchGames();
}
/// <summary>
/// Proceso de actualización del listado
/// </summary>
async Task FetchGames ()
async Task FetchGames()
{
// Indicamos que estamos ocupados (provoca que aparezca el indicador de carga)
IsBusy = true;
......@@ -128,11 +120,11 @@ namespace inutralia.ViewModels
// Llamada al API para coger el listado (provoca que se actualize la vista del listado)
try
{
Games = new ObservableRangeCollection<TrivialGame> (await App.LocalData.RefreshListAsync<TrivialGame> ());
Games = new ObservableRangeCollection<TrivialGame>(await App.LocalData.RefreshListAsync<TrivialGame>());
}
catch (System.Exception e)
{
Games.Clear ();
Games.Clear();
}
// Indicamos que ya no estamos ocupados (provoca que desaparezca el indicador de carga)
......
......@@ -14,34 +14,34 @@
-->
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:inutralia;assembly=inutralia"
xmlns:conv="clr-namespace:inutralia.Converters;assembly=inutralia"
xmlns:views="clr-namespace:inutralia.Views;assembly=inutralia"
x:Class="inutralia.Views.ArticleListView"
x:Name="ArticleListView"
BackgroundColor="White"
Title="Articulos"
>
Title="Articulos">
<ContentPage.Resources>
<ResourceDictionary>
<conv:ImageTransformator x:Key="cnvImg"></conv:ImageTransformator>
</ResourceDictionary>
</ContentPage.Resources>
<!-- Este es el componente para el listado. Primero configura de dónde obtiene los datos
y el método al que llamar cuando se hace tap en un elemento de la lista. Luego
configura el pull-to-refresh. Por último algunas opciones de visionado y gestión
de memoria
-->
<ListView
SeparatorVisibility="None"
SeparatorColor="{ DynamicResource ListViewSeparatorColor }"
Footer=""
ItemsSource="{Binding Articles}"
RowHeight="240"
ItemTapped="ItemTapped"
HasUnevenRows="false"
x:Name="listArticle">
<ListView SeparatorVisibility="None"
SeparatorColor="{ DynamicResource ListViewSeparatorColor }"
Footer=""
ItemsSource="{Binding Articles}"
RowHeight="240"
ItemTapped="ItemTapped"
HasUnevenRows="false"
x:Name="listArticle">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
......
......@@ -4,17 +4,16 @@ using Xamarin.Forms;
namespace inutralia.Views
{
public partial class ArticleListView : ContentPage
{
// Accesor al ViewModel
protected ArticleListViewModel ViewModel => BindingContext as ArticleListViewModel;
public partial class ArticleListView : ContentPage
{
// Accesor al ViewModel
protected ArticleListViewModel ViewModel => BindingContext as ArticleListViewModel;
public ArticleListView()
{
InitializeComponent();
BindingContext = new ArticleListViewModel();
}
public ArticleListView()
{
InitializeComponent();
BindingContext = new ArticleListViewModel();
}
/// <summary>
/// Método llamado al hacer tap en un elemento de la lista. Navega a la página de detalle
......@@ -23,7 +22,7 @@ namespace inutralia.Views
/// <param name="sender">La ListView</param>
/// <param name="e">Argumentos del evento</param>
void ItemTapped(object sender, ItemTappedEventArgs e)
{
{
// e.Item apunta a la notificación seleccionada. A partir de ella se crea su ViewModel
// y con él se crea la página de detalle y se navega a ella
Navigation.PushAsync(
......@@ -35,17 +34,17 @@ namespace inutralia.Views
// Deselecciona el item para que no le cambie el color de fondo
((ListView)sender).SelectedItem = null;
}
}
/// <summary>
/// Método llamado cada vez que una página pasa a ser visible
/// </summary>
protected override async void OnAppearing()
{
base.OnAppearing();
/// <summary>
/// Método llamado cada vez que una página pasa a ser visible
/// </summary>
protected override async void OnAppearing()
{
base.OnAppearing();
// Le decimos al ViewModel que realice la primera carga del listado
await ViewModel.ExecuteLoadArticlesCommand();
}
}
// Le decimos al ViewModel que realice la primera carga del listado
await ViewModel.ExecuteLoadArticlesCommand();
}
}
}
......@@ -3,14 +3,10 @@
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="inutralia.Views.ArticleViewPage"
xmlns:local="clr-namespace:inutralia;assembly=inutralia"
xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
xmlns:fftransformations="clr-namespace:FFImageLoading.Transformations;assembly=FFImageLoading.Transformations"
xmlns:artina="clr-namespace:UXDivers.Artina.Shared;assembly=UXDivers.Artina.Shared"
BackgroundColor="{ DynamicResource MainWrapperBackgroundColor }">
xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
BackgroundColor="{ DynamicResource MainWrapperBackgroundColor }">
<ScrollView x:Name="outerScrollView">
<Grid
x:Name="layeringGrid"
RowSpacing="0"
......@@ -61,15 +57,6 @@
Margin="10"
HorizontalOptions="CenterAndExpand"
VerticalOptions="Center"/>
<!--<Label
Text="{ Binding Article.Subtitle }"
LineBreakMode="WordWrap"
TextColor="{ DynamicResource OverImageTextColor }"
FontSize="16"/>
<BoxView
Style="{StaticResource BrandNameOrnamentStyle}"
Margin="0,20,0,0"/>-->
</Grid>
</StackLayout>
......@@ -111,8 +98,6 @@
FontSize="14"
TextColor="{ DynamicResource BaseTextColor }"
HorizontalOptions="End"/>
</StackLayout>
<!-- SEPARATOR (CAJA EN LA QUE SE INCLUYEN LAS DOS VARIABLES ANTERIORES (ARTICULO Y FECHA)) -->
......@@ -170,5 +155,4 @@
</StackLayout>
</Grid>
</ScrollView>
</ContentPage>
......@@ -4,70 +4,72 @@ using Xamarin.Forms;
namespace inutralia.Views
{
public partial class ArticleViewPage : ContentPage
{
public partial class ArticleViewPage : ContentPage
{
public ArticleViewPage()
{
InitializeComponent();
}
public ArticleViewPage (ArticleDetailViewModel viewModel)
{
InitializeComponent ();
BindingContext = viewModel;
}
protected override void OnAppearing (){
base.OnAppearing ();
public ArticleViewPage(ArticleDetailViewModel viewModel)
{
InitializeComponent();
BindingContext = viewModel;
}
outerScrollView.Scrolled += OnScroll;
}
protected override void OnAppearing()
{
base.OnAppearing();
outerScrollView.Scrolled += OnScroll;
}
protected override void OnDisappearing ()
{
base.OnDisappearing ();
outerScrollView.Scrolled -= OnScroll;
}
protected override void OnDisappearing()
{
base.OnDisappearing();
outerScrollView.Scrolled -= OnScroll;
}
public void OnScroll (object sender, ScrolledEventArgs e) {
var imageHeight = img.Height * 2;
var scrollRegion = layeringGrid.Height - outerScrollView.Height;
var parallexRegion = imageHeight - outerScrollView.Height;
var factor = outerScrollView.ScrollY - parallexRegion * (outerScrollView.ScrollY / scrollRegion);
if (factor < 0)
{
factor = 0;
}
else
{
if (img.TranslationY > img.Height)
{
factor = img.Height;
}
else if( img.TranslationY > outerScrollView.ScrollY ){
img.TranslationY = outerScrollView.ScrollY;
}
}
img.TranslationY = factor;
img.Opacity = 1 - ( factor / imageHeight ) ;
//headers.Scale = 1 - ( (factor ) / (imageHeight * 2) ) ;
}
public void OnScroll(object sender, ScrolledEventArgs e)
{
var imageHeight = img.Height * 2;
var scrollRegion = layeringGrid.Height - outerScrollView.Height;
var parallexRegion = imageHeight - outerScrollView.Height;
var factor = outerScrollView.ScrollY - parallexRegion * (outerScrollView.ScrollY / scrollRegion);
public void OnMore (object sender, EventArgs e) {
var mi = ((MenuItem)sender);
DisplayAlert("More Context Action", mi.CommandParameter + " more context action", "OK");
}
if (factor < 0)
{
factor = 0;
}
public void OnDelete (object sender, EventArgs e) {
var mi = ((MenuItem)sender);
DisplayAlert("Delete Context Action", mi.CommandParameter + " delete context action", "OK");
}
else
{
if (img.TranslationY > img.Height)
{
factor = img.Height;
}
else if (img.TranslationY > outerScrollView.ScrollY)
{
img.TranslationY = outerScrollView.ScrollY;
}
}
img.TranslationY = factor;
img.Opacity = 1 - (factor / imageHeight);
//headers.Scale = 1 - ( (factor ) / (imageHeight * 2) ) ;
}
public void OnMore(object sender, EventArgs e)
{
var mi = ((MenuItem)sender);
DisplayAlert("More Context Action", mi.CommandParameter + " more context action", "OK");
}
public void OnPrimaryActionButtonClicked (object sender, EventArgs e){
public void OnDelete(object sender, EventArgs e)
{
var mi = ((MenuItem)sender);
DisplayAlert("Delete Context Action", mi.CommandParameter + " delete context action", "OK");
}
}
}
public void OnPrimaryActionButtonClicked(object sender, EventArgs e) { }
}
}
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