239 lines
7.8 KiB
C#
239 lines
7.8 KiB
C#
using Billing.Languages;
|
|
using Billing.Models;
|
|
using Billing.Store;
|
|
using Billing.UI;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Xamarin.Forms;
|
|
|
|
namespace Billing.Views
|
|
{
|
|
public partial class CategoryPage : BillingPage
|
|
{
|
|
private static readonly BindableProperty CategoriesProperty = Helper.Create<IList, CategoryPage>(nameof(Categories));
|
|
private static readonly BindableProperty IsTopCategoryProperty = Helper.Create<bool, CategoryPage>(nameof(IsTopCategory));
|
|
|
|
public IList Categories
|
|
{
|
|
get => (IList)GetValue(CategoriesProperty);
|
|
set => SetValue(CategoriesProperty, value);
|
|
}
|
|
public bool IsTopCategory => (bool)GetValue(IsTopCategoryProperty);
|
|
|
|
public Command LongPressed { get; }
|
|
public Command Tapped { get; }
|
|
|
|
private readonly int parentId;
|
|
private readonly Category parent;
|
|
|
|
public CategoryPage(int pid = -1)
|
|
{
|
|
parentId = pid;
|
|
parent = App.Categories.FirstOrDefault(c => c.Id == pid);
|
|
Title = parent?.Name ?? Resource.CategoryManage;
|
|
|
|
if (parent != null)
|
|
{
|
|
SetValue(IsTopCategoryProperty, false);
|
|
Categories = App.Categories.Where(c => c.ParentId == pid).Select(c => WrapCategory(c)).ToList();
|
|
ToolbarItems.Add(new ToolbarItem
|
|
{
|
|
Order = ToolbarItemOrder.Primary,
|
|
IconImageSource = "plus.png",
|
|
Command = new Command(OnAddCategory)
|
|
});
|
|
}
|
|
else
|
|
{
|
|
SetValue(IsTopCategoryProperty, true);
|
|
Categories = new List<CategoryGrouping>
|
|
{
|
|
new(Resource.Spending, App.Categories.Where(c => c.Type == CategoryType.Spending && c.ParentId == null).Select(c => WrapCategory(c))),
|
|
new(Resource.Income, App.Categories.Where(c => c.Type == CategoryType.Income && c.ParentId == null).Select(c => WrapCategory(c)))
|
|
};
|
|
}
|
|
|
|
LongPressed = new Command(OnLongPressed);
|
|
Tapped = new Command(OnTapped);
|
|
|
|
InitializeComponent();
|
|
}
|
|
|
|
private UICategory WrapCategory(Category category)
|
|
{
|
|
return new UICategory(category)
|
|
{
|
|
Icon = category.Icon,
|
|
Name = category.Name,
|
|
IsTopCategory = IsTopCategory,
|
|
TintColor = category.TintColor
|
|
};
|
|
}
|
|
|
|
private async void OnAddCategory()
|
|
{
|
|
if (Tap.IsBusy)
|
|
{
|
|
return;
|
|
}
|
|
using (Tap.Start())
|
|
{
|
|
var page = new AddCategoryPage(parent: parent);
|
|
page.CategoryChecked += OnCategoryChecked;
|
|
await Navigation.PushAsync(page);
|
|
}
|
|
}
|
|
|
|
private async void OnLongPressed(object o)
|
|
{
|
|
if (Tap.IsBusy)
|
|
{
|
|
return;
|
|
}
|
|
using (Tap.Start())
|
|
{
|
|
if (o is UICategory c)
|
|
{
|
|
if (parentId < 0)
|
|
{
|
|
var page = new AddCategoryPage(c.Category.Id);
|
|
page.CategoryChecked += OnCategoryChecked;
|
|
await Navigation.PushAsync(page);
|
|
}
|
|
else
|
|
{
|
|
var result = await this.ShowConfirm(string.Format(Resource.ConfirmDeleteCategory, c.Category.Name));
|
|
if (result)
|
|
{
|
|
Categories.Remove(c);
|
|
groupLayout.Refresh(Categories);
|
|
App.Categories.Remove(c.Category);
|
|
await StoreHelper.DeleteCategoryItemAsync(c.Category);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private async void OnTapped(object o)
|
|
{
|
|
if (Tap.IsBusy)
|
|
{
|
|
return;
|
|
}
|
|
using (Tap.Start())
|
|
{
|
|
if (o is UICategory c)
|
|
{
|
|
if (parentId < 0)
|
|
{
|
|
var page = new CategoryPage(c.Category.Id);
|
|
await Navigation.PushAsync(page);
|
|
}
|
|
else
|
|
{
|
|
var page = new AddCategoryPage(c.Category.Id);
|
|
page.CategoryChecked += OnCategoryChecked;
|
|
await Navigation.PushAsync(page);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private async void OnCategoryChecked(object sender, Category category)
|
|
{
|
|
if (category.Id <= 0)
|
|
{
|
|
// add
|
|
App.Categories.Add(category);
|
|
Categories.Add(WrapCategory(category));
|
|
}
|
|
else
|
|
{
|
|
foreach (var o in Categories)
|
|
{
|
|
if (o is CategoryGrouping grouping)
|
|
{
|
|
var c = grouping.FirstOrDefault(c => c.Category == category);
|
|
if (c != null)
|
|
{
|
|
UpdateCategory(c);
|
|
}
|
|
}
|
|
else if (o is UICategory c && c.Category == category)
|
|
{
|
|
UpdateCategory(c);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
groupLayout.Refresh(Categories);
|
|
|
|
await StoreHelper.SaveCategoryItemAsync(category);
|
|
}
|
|
|
|
private void UpdateCategory(UICategory c)
|
|
{
|
|
c.Name = c.Category.Name;
|
|
c.Icon = c.Category.Icon;
|
|
c.TintColor = c.Category.TintColor;
|
|
}
|
|
}
|
|
|
|
public class UICategory : BindableObject
|
|
{
|
|
public static readonly BindableProperty IsCheckedProperty = Helper.Create<bool, UICategory>(nameof(IsChecked));
|
|
public static readonly BindableProperty IconProperty = Helper.Create<string, UICategory>(nameof(Icon));
|
|
public static readonly BindableProperty NameProperty = Helper.Create<string, UICategory>(nameof(Name));
|
|
public static readonly BindableProperty TintColorProperty = Helper.Create<long, UICategory>(nameof(TintColor));
|
|
public static readonly BindableProperty IsTopCategoryProperty = Helper.Create<bool, UICategory>(nameof(IsTopCategory));
|
|
|
|
public bool IsChecked
|
|
{
|
|
get => (bool)GetValue(IsCheckedProperty);
|
|
set => SetValue(IsCheckedProperty, value);
|
|
}
|
|
public string Icon
|
|
{
|
|
get => (string)GetValue(IconProperty);
|
|
set => SetValue(IconProperty, value);
|
|
}
|
|
public string Name
|
|
{
|
|
get => (string)GetValue(NameProperty);
|
|
set => SetValue(NameProperty, value);
|
|
}
|
|
public long TintColor
|
|
{
|
|
get => (long)GetValue(TintColorProperty);
|
|
set => SetValue(TintColorProperty, value);
|
|
}
|
|
public bool IsTopCategory
|
|
{
|
|
get => (bool)GetValue(IsTopCategoryProperty);
|
|
set => SetValue(IsTopCategoryProperty, value);
|
|
}
|
|
|
|
public Category Category { get; }
|
|
|
|
public UICategory(Category category)
|
|
{
|
|
Category = category;
|
|
}
|
|
}
|
|
|
|
public class CategoryGrouping : List<UICategory>, IGrouping<string, UICategory>
|
|
{
|
|
public string Key { get; }
|
|
|
|
public CategoryGrouping(string key) : base()
|
|
{
|
|
Key = key;
|
|
}
|
|
public CategoryGrouping(string key, IEnumerable<UICategory> categories) : base(categories)
|
|
{
|
|
Key = key;
|
|
}
|
|
}
|
|
} |