filter conditions
This commit is contained in:
parent
84ec2df987
commit
74053a328e
@ -20,6 +20,14 @@
|
||||
<TapToMemo>Click here to record</TapToMemo>
|
||||
<TitleDateFormat>MM/dd/yyyy</TitleDateFormat>
|
||||
<DateRangeFormat>MM/dd</DateRangeFormat>
|
||||
<To>To</To>
|
||||
<Monthly>Monthly</Monthly>
|
||||
<Today>Today</Today>
|
||||
<PastMonth>Past Month</PastMonth>
|
||||
<PastQuarter>Past Quarter</PastQuarter>
|
||||
<PastSixMonths>Past Six Months</PastSixMonths>
|
||||
<PastYear>Past Year</PastYear>
|
||||
<Total>Total</Total>
|
||||
<Balance>Balance</Balance>
|
||||
<Assets>Assets</Assets>
|
||||
<Liability>Liability</Liability>
|
||||
|
@ -20,6 +20,14 @@
|
||||
<TapToMemo>点此记录</TapToMemo>
|
||||
<TitleDateFormat>yyyy年MM月dd日</TitleDateFormat>
|
||||
<DateRangeFormat>MM月dd日</DateRangeFormat>
|
||||
<To>至</To>
|
||||
<Monthly>当月</Monthly>
|
||||
<Today>今日</Today>
|
||||
<PastMonth>一个月</PastMonth>
|
||||
<PastQuarter>一个季度</PastQuarter>
|
||||
<PastSixMonths>六个月</PastSixMonths>
|
||||
<PastYear>一年</PastYear>
|
||||
<Total>全部</Total>
|
||||
<Balance>余额</Balance>
|
||||
<Assets>资产</Assets>
|
||||
<Liability>负债</Liability>
|
||||
|
@ -8,6 +8,8 @@ namespace Billing.UI
|
||||
{
|
||||
public event EventHandler Loaded;
|
||||
|
||||
private bool loaded;
|
||||
|
||||
public BillingPage()
|
||||
{
|
||||
SetDynamicResource(BackgroundColorProperty, BaseTheme.WindowBackgroundColor);
|
||||
@ -18,5 +20,14 @@ namespace Billing.UI
|
||||
{
|
||||
Loaded?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public void TriggerLoad()
|
||||
{
|
||||
if (!loaded)
|
||||
{
|
||||
loaded = true;
|
||||
OnLoaded();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -8,15 +8,19 @@ namespace Billing.UI
|
||||
{
|
||||
public class ColorPicker : SKCanvasView
|
||||
{
|
||||
public static readonly BindableProperty ColorProperty = BindableProperty.Create(nameof(Color), typeof(Color), typeof(ColorPicker));
|
||||
public static readonly BindableProperty ColorProperty = Helper.Create<Color, ColorPicker>(nameof(Color));
|
||||
public static readonly BindableProperty CommandProperty = Helper.Create<Command, ColorPicker>(nameof(Command));
|
||||
|
||||
public Color Color
|
||||
{
|
||||
get => (Color)GetValue(ColorProperty);
|
||||
set => SetValue(ColorProperty, value);
|
||||
}
|
||||
|
||||
public event EventHandler<Color> ColorChanged;
|
||||
public Command Command
|
||||
{
|
||||
get => (Command)GetValue(CommandProperty);
|
||||
set => SetValue(CommandProperty, value);
|
||||
}
|
||||
|
||||
private SKPoint? lastTouch;
|
||||
|
||||
@ -116,7 +120,7 @@ namespace Billing.UI
|
||||
|
||||
var color = touchColor.ToFormsColor();
|
||||
Color = color;
|
||||
ColorChanged?.Invoke(this, color);
|
||||
Command?.Execute(color);
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,8 +130,8 @@ namespace Billing.UI
|
||||
lastTouch = e.Location;
|
||||
|
||||
var size = CanvasSize;
|
||||
if ((e.Location.X > 0 && e.Location.X < size.Width) &&
|
||||
(e.Location.Y > 0 && e.Location.Y < size.Height))
|
||||
if (e.Location.X > 0 && e.Location.X < size.Width &&
|
||||
e.Location.Y > 0 && e.Location.Y < size.Height)
|
||||
{
|
||||
e.Handled = true;
|
||||
InvalidateSurface();
|
||||
|
@ -92,6 +92,12 @@ namespace Billing.UI
|
||||
var result = await page.DisplayActionSheet(message, Resource.No, yes);
|
||||
return result == yes;
|
||||
}
|
||||
|
||||
public static DateTime LastMoment(this DateTime date)
|
||||
{
|
||||
// add 23:59:59.999...
|
||||
return date.AddTicks(863999999999);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ModelExtensionHelper
|
||||
|
@ -73,15 +73,9 @@ namespace Billing.Views
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private bool focused;
|
||||
|
||||
public override void OnLoaded()
|
||||
{
|
||||
if (!focused)
|
||||
{
|
||||
focused = true;
|
||||
editorName.SetFocus();
|
||||
}
|
||||
editorName.SetFocus();
|
||||
}
|
||||
|
||||
private async void OnCheckAccount()
|
||||
|
@ -116,15 +116,9 @@ namespace Billing.Views
|
||||
}
|
||||
}
|
||||
|
||||
private bool focused;
|
||||
|
||||
public override void OnLoaded()
|
||||
{
|
||||
if (!focused)
|
||||
{
|
||||
focused = true;
|
||||
editorAmount.SetFocus();
|
||||
}
|
||||
editorAmount.SetFocus();
|
||||
}
|
||||
|
||||
private async void OnCheckBill()
|
||||
|
@ -41,7 +41,7 @@
|
||||
<ViewCell Height="120">
|
||||
<Grid BackgroundColor="{DynamicResource OptionTintColor}"
|
||||
ColumnDefinitions=".35*, .65*" Padding="10">
|
||||
<ui:ColorPicker Grid.Column="1" ColorChanged="ColorPicker_ColorChanged"/>
|
||||
<ui:ColorPicker Grid.Column="1" Command="{Binding ColorPickerCommand}"/>
|
||||
</Grid>
|
||||
</ViewCell>
|
||||
</TableSection>
|
||||
|
@ -38,6 +38,7 @@ namespace Billing.Views
|
||||
|
||||
public Command CheckCategory { get; }
|
||||
public Command SelectIcon { get; }
|
||||
public Command ColorPickerCommand { get; }
|
||||
|
||||
public event EventHandler<Category> CategoryChecked;
|
||||
|
||||
@ -73,25 +74,23 @@ namespace Billing.Views
|
||||
|
||||
CheckCategory = new Command(OnCheckCategory);
|
||||
SelectIcon = new Command(OnSelectIcon);
|
||||
ColorPickerCommand = new Command(OnColorPickerCommand);
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private bool focused;
|
||||
|
||||
public override void OnLoaded()
|
||||
{
|
||||
if (!focused)
|
||||
{
|
||||
focused = true;
|
||||
editorName.SetFocus();
|
||||
}
|
||||
editorName.SetFocus();
|
||||
}
|
||||
|
||||
private void ColorPicker_ColorChanged(object sender, Color e)
|
||||
private void OnColorPickerCommand(object o)
|
||||
{
|
||||
TintColor = e;
|
||||
TintColorString = Helper.WrapColorString(e.ToHex());
|
||||
if (o is Color color)
|
||||
{
|
||||
TintColor = color;
|
||||
TintColorString = Helper.WrapColorString(color.ToHex());
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnCheckCategory()
|
||||
|
@ -44,8 +44,6 @@ namespace Billing.Views
|
||||
public Command EditBilling { get; }
|
||||
public Command DeleteBilling { get; }
|
||||
|
||||
private bool initialized;
|
||||
|
||||
public BillPage()
|
||||
{
|
||||
TitleDateTap = new Command(OnTitleDateTapped);
|
||||
@ -58,11 +56,7 @@ namespace Billing.Views
|
||||
|
||||
public override void OnLoaded()
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
initialized = true;
|
||||
billingDate.SetDateTime(DateTime.Today);
|
||||
}
|
||||
billingDate.SetDateTime(DateTime.Today);
|
||||
}
|
||||
|
||||
private void OnDateSelected(object sender, DateEventArgs e)
|
||||
|
@ -4,6 +4,7 @@
|
||||
xmlns:ui="clr-namespace:Billing.UI"
|
||||
xmlns:v="clr-namespace:Billing.Views"
|
||||
xmlns:chart="clr-namespace:Microcharts.Forms;assembly=Microcharts.Forms"
|
||||
xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="Billing.Views.RankPage"
|
||||
x:Name="rankPage"
|
||||
@ -13,7 +14,7 @@
|
||||
|
||||
<Shell.TitleView>
|
||||
<Grid>
|
||||
<StackLayout Margin="30, 0, 0, 0" HorizontalOptions="Center" VerticalOptions="Center"
|
||||
<StackLayout HorizontalOptions="Center" VerticalOptions="Center"
|
||||
Orientation="Horizontal" Spacing="10">
|
||||
<ui:TintImageButton Source="left.png" WidthRequest="20" HeightRequest="20"
|
||||
VerticalOptions="Center" HorizontalOptions="Start"
|
||||
@ -21,6 +22,9 @@
|
||||
<Label Text="{Binding Title}"
|
||||
TextColor="{DynamicResource PrimaryColor}"
|
||||
FontSize="{OnPlatform Android=20, iOS=18}">
|
||||
<Label.GestureRecognizers>
|
||||
<TapGestureRecognizer Command="{Binding FilterCommand}"/>
|
||||
</Label.GestureRecognizers>
|
||||
<Label.FontFamily>
|
||||
<OnPlatform x:TypeArguments="x:String"
|
||||
Android="OpenSans-SemiBold.ttf#OpenSans-SemiBold"
|
||||
@ -34,9 +38,9 @@
|
||||
</Grid>
|
||||
</Shell.TitleView>
|
||||
|
||||
<ContentPage.ToolbarItems>
|
||||
<!--<ContentPage.ToolbarItems>
|
||||
<ToolbarItem Order="Primary" IconImageSource="filter.png" Command="{Binding FilterCommand}"/>
|
||||
</ContentPage.ToolbarItems>
|
||||
</ContentPage.ToolbarItems>-->
|
||||
|
||||
<ContentPage.Resources>
|
||||
<ui:NegativeConverter x:Key="negativeConverter"/>
|
||||
@ -48,7 +52,7 @@
|
||||
<Style x:Key="titleLabel" TargetType="Label">
|
||||
<Setter Property="FontSize" Value="16"/>
|
||||
<Setter Property="Margin" Value="10, 20, 10, 10"/>
|
||||
<!--<Setter Property="TextColor" Value="{DynamicResource SecondaryTextColor}"/>-->
|
||||
<Setter Property="TextColor" Value="{DynamicResource TextColor}"/>
|
||||
</Style>
|
||||
<Style x:Key="promptLabel" TargetType="Label">
|
||||
<Setter Property="HeightRequest" Value="240"/>
|
||||
@ -58,12 +62,16 @@
|
||||
<Setter Property="VerticalTextAlignment" Value="Center"/>
|
||||
<Setter Property="TextColor" Value="{DynamicResource SecondaryTextColor}"/>
|
||||
</Style>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="TextColor" Value="{DynamicResource TextColor}"/>
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
</Style>
|
||||
</ContentPage.Resources>
|
||||
|
||||
<Grid>
|
||||
<ScrollView x:Name="scroller">
|
||||
<ScrollView x:Name="scroller" Scrolled="Scroller_Scrolled">
|
||||
<StackLayout>
|
||||
<Grid Margin="0, 10, 0, 0" Padding="8" ColumnSpacing="8" ColumnDefinitions="*, Auto" HeightRequest="24"
|
||||
<Grid Padding="8" ColumnSpacing="8" ColumnDefinitions="*, Auto" HeightRequest="24"
|
||||
BackgroundColor="{DynamicResource PromptBackgroundColor}">
|
||||
<StackLayout Grid.Column="1" Orientation="Horizontal" Spacing="6">
|
||||
<Label Text="{r:Text Income}" TextColor="{DynamicResource GreenColor}"
|
||||
@ -133,7 +141,7 @@
|
||||
<ui:BlurryPanel x:Name="panelFilter" VerticalOptions="Start" Opacity="0"
|
||||
BackgroundColor="{DynamicResource WindowBackgroundColor}"
|
||||
HeightRequest="{Binding Height, Source={x:Reference gridFilter}}"/>
|
||||
<Grid x:Name="gridFilter" VerticalOptions="Start" Opacity="0" Padding="10">
|
||||
<Grid x:Name="gridFilter" VerticalOptions="Start" Opacity="0" Padding="10" RowDefinitions="Auto, Auto, Auto">
|
||||
<ui:SegmentedControl Margin="6, 6, 6, 3" VerticalOptions="Center"
|
||||
SelectedSegmentIndex="{Binding SegmentType, Mode=TwoWay}"
|
||||
SelectedTextColor="{DynamicResource TextColor}"
|
||||
@ -143,6 +151,33 @@
|
||||
<ui:SegmentedControlOption Text="{r:Text Income}"/>
|
||||
</ui:SegmentedControl.Children>
|
||||
</ui:SegmentedControl>
|
||||
<ScrollView Grid.Row="1" Margin="6, 6, 6, 3">
|
||||
<ui:SegmentedControl SelectedSegmentIndex="{Binding SegmentDate, Mode=TwoWay}"
|
||||
SelectedTextColor="{DynamicResource TextColor}"
|
||||
TintColor="{DynamicResource PromptBackgroundColor}">
|
||||
<ui:SegmentedControl.Children>
|
||||
<ui:SegmentedControlOption Text="{r:Text Monthly}"/>
|
||||
<ui:SegmentedControlOption Text="{r:Text Today}"/>
|
||||
<ui:SegmentedControlOption Text="{r:Text PastMonth}"/>
|
||||
<ui:SegmentedControlOption Text="{r:Text PastQuarter}"/>
|
||||
<ui:SegmentedControlOption Text="{r:Text PastSixMonths}"/>
|
||||
<ui:SegmentedControlOption Text="{r:Text PastYear}"/>
|
||||
<ui:SegmentedControlOption Text="{r:Text Total}"/>
|
||||
</ui:SegmentedControl.Children>
|
||||
</ui:SegmentedControl>
|
||||
</ScrollView>
|
||||
<Grid Grid.Row="2" ColumnDefinitions="*, Auto, *" Margin="0, 10">
|
||||
<ui:OptionDatePicker Date="{Binding StartPickerDate, Mode=TwoWay}"
|
||||
FontSize="16" TextColor="{DynamicResource TextColor}"
|
||||
VerticalOptions="Center"
|
||||
ios:DatePicker.UpdateMode="WhenFinished"/>
|
||||
<Label Grid.Column="1" Text="{r:Text To}" TextColor="{DynamicResource SecondaryTextColor}"
|
||||
VerticalOptions="Center"/>
|
||||
<ui:OptionDatePicker Grid.Column="2" Date="{Binding EndPickerDate, Mode=TwoWay}"
|
||||
FontSize="16" TextColor="{DynamicResource TextColor}"
|
||||
VerticalOptions="Center"
|
||||
ios:DatePicker.UpdateMode="WhenFinished"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ui:BillingPage>
|
@ -16,7 +16,22 @@ namespace Billing.Views
|
||||
{
|
||||
public partial class RankPage : BillingPage
|
||||
{
|
||||
private static readonly DateTime today = DateTime.Today;
|
||||
|
||||
private static readonly BindableProperty SegmentTypeProperty = Helper.Create<int, RankPage>(nameof(SegmentType), defaultValue: 0, propertyChanged: OnSegmentTypeChanged);
|
||||
private static readonly BindableProperty SegmentDateProperty = Helper.Create<int, RankPage>(nameof(SegmentDate), defaultValue: 0, propertyChanged: OnSegmentDateChanged);
|
||||
private static readonly BindableProperty StartDateProperty = Helper.Create<DateTime, RankPage>(nameof(StartDate),
|
||||
defaultValue: today.AddDays(1 - today.Day),
|
||||
propertyChanged: OnDateChanged);
|
||||
private static readonly BindableProperty EndDateProperty = Helper.Create<DateTime, RankPage>(nameof(EndDate),
|
||||
defaultValue: today.AddDays(DateTime.DaysInMonth(today.Year, today.Month) - today.Day).LastMoment(),
|
||||
propertyChanged: OnDateChanged);
|
||||
private static readonly BindableProperty StartPickerDateProperty = Helper.Create<DateTime, RankPage>(nameof(StartPickerDate),
|
||||
defaultValue: today.AddDays(1 - today.Day),
|
||||
propertyChanged: OnPickerStartDateChanged);
|
||||
private static readonly BindableProperty EndPickerDateProperty = Helper.Create<DateTime, RankPage>(nameof(EndPickerDate),
|
||||
defaultValue: today.AddDays(DateTime.DaysInMonth(today.Year, today.Month) - today.Day),
|
||||
propertyChanged: OnPickerEndDateChanged);
|
||||
private static readonly BindableProperty ChartProperty = Helper.Create<Chart, RankPage>(nameof(Chart));
|
||||
private static readonly BindableProperty CategoryChartProperty = Helper.Create<Chart, RankPage>(nameof(CategoryChart));
|
||||
private static readonly BindableProperty TopBillsProperty = Helper.Create<IList<UIBill>, RankPage>(nameof(TopBills));
|
||||
@ -34,8 +49,40 @@ namespace Billing.Views
|
||||
1 => CategoryType.Income,
|
||||
_ => CategoryType.Spending
|
||||
};
|
||||
page.OnFilterCommand(false);
|
||||
page.SetMonth(page.current);
|
||||
page.LoadData();
|
||||
}
|
||||
private static void OnSegmentDateChanged(RankPage page, int old, int @new)
|
||||
{
|
||||
page.OnDateTypeCommand(@new);
|
||||
}
|
||||
private static void OnDateChanged(RankPage page, DateTime old = default, DateTime @new = default)
|
||||
{
|
||||
page.isLocked = true;
|
||||
page.StartPickerDate = page.StartDate;
|
||||
page.EndPickerDate = page.EndDate;
|
||||
page.isLocked = false;
|
||||
if (!page.isFreezed)
|
||||
{
|
||||
var format = Resource.TitleDateFormat;
|
||||
page.Title = page.StartDate.ToString(format) + " ~ " + page.EndDate.ToString(format);
|
||||
page.LoadData();
|
||||
}
|
||||
}
|
||||
private static void OnPickerStartDateChanged(RankPage page, DateTime _, DateTime @new)
|
||||
{
|
||||
if (!page.isLocked)
|
||||
{
|
||||
page.SegmentDate = -1;
|
||||
page.StartDate = @new;
|
||||
}
|
||||
}
|
||||
private static void OnPickerEndDateChanged(RankPage page, DateTime _, DateTime @new)
|
||||
{
|
||||
if (!page.isLocked)
|
||||
{
|
||||
page.SegmentDate = -1;
|
||||
page.EndDate = @new;
|
||||
}
|
||||
}
|
||||
|
||||
public int SegmentType
|
||||
@ -43,6 +90,31 @@ namespace Billing.Views
|
||||
get => (int)GetValue(SegmentTypeProperty);
|
||||
set => SetValue(SegmentTypeProperty, value);
|
||||
}
|
||||
public int SegmentDate
|
||||
{
|
||||
get => (int)GetValue(SegmentDateProperty);
|
||||
set => SetValue(SegmentDateProperty, value);
|
||||
}
|
||||
public DateTime StartDate
|
||||
{
|
||||
get => (DateTime)GetValue(StartDateProperty);
|
||||
set => SetValue(StartDateProperty, value);
|
||||
}
|
||||
public DateTime EndDate
|
||||
{
|
||||
get => (DateTime)GetValue(EndDateProperty);
|
||||
set => SetValue(EndDateProperty, value);
|
||||
}
|
||||
public DateTime StartPickerDate
|
||||
{
|
||||
get => (DateTime)GetValue(StartPickerDateProperty);
|
||||
set => SetValue(StartPickerDateProperty, value);
|
||||
}
|
||||
public DateTime EndPickerDate
|
||||
{
|
||||
get => (DateTime)GetValue(EndPickerDateProperty);
|
||||
set => SetValue(EndPickerDateProperty, value);
|
||||
}
|
||||
public Chart Chart
|
||||
{
|
||||
get => (Chart)GetValue(ChartProperty);
|
||||
@ -82,11 +154,11 @@ namespace Billing.Views
|
||||
public Command FilterCommand { get; }
|
||||
public Command EditBilling { get; }
|
||||
|
||||
private DateTime current;
|
||||
private DateTime end;
|
||||
private IEnumerable<Bill> bills;
|
||||
private CategoryType type = CategoryType.Spending;
|
||||
private bool isFilterToggled;
|
||||
private bool isFreezed;
|
||||
private bool isLocked;
|
||||
|
||||
private readonly SKTypeface font;
|
||||
|
||||
@ -111,7 +183,76 @@ namespace Billing.Views
|
||||
|
||||
public override void OnLoaded()
|
||||
{
|
||||
SetMonth(DateTime.Today);
|
||||
OnDateChanged(this);
|
||||
}
|
||||
|
||||
private void OnDateTypeCommand(int index)
|
||||
{
|
||||
if (index < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (scroller.ScrollY > 0)
|
||||
{
|
||||
scroller.ScrollToAsync(0, 0, true);
|
||||
}
|
||||
isFreezed = true;
|
||||
var today = DateTime.Today;
|
||||
switch (index)
|
||||
{
|
||||
case 0: // monthly
|
||||
StartDate = today.AddDays(1 - today.Day);
|
||||
EndDate = today.AddDays(DateTime.DaysInMonth(today.Year, today.Month) - today.Day).LastMoment();
|
||||
break;
|
||||
case 1: // today
|
||||
StartDate = today;
|
||||
EndDate = today.LastMoment();
|
||||
break;
|
||||
case 2: // past month
|
||||
StartDate = today.AddMonths(-1).AddDays(1);
|
||||
EndDate = today.LastMoment();
|
||||
break;
|
||||
case 3: // past quarter
|
||||
StartDate = today.AddMonths(-3).AddDays(1);
|
||||
EndDate = today.LastMoment();
|
||||
break;
|
||||
case 4: // past six months
|
||||
StartDate = today.AddMonths(-6).AddDays(1);
|
||||
EndDate = today.LastMoment();
|
||||
break;
|
||||
case 5: // past year
|
||||
StartDate = today.AddYears(-1).AddDays(1);
|
||||
EndDate = today.LastMoment();
|
||||
break;
|
||||
case 6: // total
|
||||
//StartDate = App.Bills.Min(b => b.CreateTime).Date;
|
||||
//EndDate = App.Bills.Max(b => b.CreateTime).Date.LastMoment();
|
||||
DateTime min = DateTime.MaxValue;
|
||||
DateTime max = DateTime.MinValue;
|
||||
App.Bills.ForEach(b =>
|
||||
{
|
||||
if (b.CreateTime < min)
|
||||
{
|
||||
min = b.CreateTime;
|
||||
}
|
||||
if (b.CreateTime > max)
|
||||
{
|
||||
max = b.CreateTime;
|
||||
}
|
||||
});
|
||||
StartDate = min.Date;
|
||||
EndDate = max.Date.LastMoment();
|
||||
break;
|
||||
}
|
||||
isFreezed = false;
|
||||
OnDateChanged(this);
|
||||
}
|
||||
|
||||
private bool IsPreset(DateTime start, DateTime end)
|
||||
{
|
||||
return start.Month == end.Month &&
|
||||
start.Day == 1 &&
|
||||
end.Day == DateTime.DaysInMonth(end.Year, end.Month);
|
||||
}
|
||||
|
||||
private void OnLeftCommand()
|
||||
@ -120,7 +261,29 @@ namespace Billing.Views
|
||||
{
|
||||
scroller.ScrollToAsync(0, 0, true);
|
||||
}
|
||||
SetMonth(current.AddMonths(-1));
|
||||
isFreezed = true;
|
||||
var start = StartDate;
|
||||
var end = EndDate;
|
||||
if (IsPreset(start, end))
|
||||
{
|
||||
start = start.AddMonths(-1);
|
||||
end = start.AddDays(DateTime.DaysInMonth(start.Year, start.Month) - 1).LastMoment();
|
||||
}
|
||||
else
|
||||
{
|
||||
var days = (end.Date - start.Date).TotalDays + 1;
|
||||
start = start.AddDays(-days);
|
||||
end = end.AddDays(-days);
|
||||
}
|
||||
if (start.Year < 1900)
|
||||
{
|
||||
isFreezed = false;
|
||||
return;
|
||||
}
|
||||
StartDate = start;
|
||||
EndDate = end;
|
||||
isFreezed = false;
|
||||
OnDateChanged(this);
|
||||
}
|
||||
|
||||
private void OnRightCommand()
|
||||
@ -129,7 +292,29 @@ namespace Billing.Views
|
||||
{
|
||||
scroller.ScrollToAsync(0, 0, true);
|
||||
}
|
||||
SetMonth(current.AddMonths(1));
|
||||
isFreezed = true;
|
||||
var start = StartDate;
|
||||
var end = EndDate;
|
||||
if (IsPreset(start, end))
|
||||
{
|
||||
start = start.AddMonths(1);
|
||||
end = start.AddDays(DateTime.DaysInMonth(start.Year, start.Month) - 1).LastMoment();
|
||||
}
|
||||
else
|
||||
{
|
||||
var days = (end.Date - start.Date).TotalDays + 1;
|
||||
start = start.AddDays(days);
|
||||
end = end.AddDays(days);
|
||||
}
|
||||
if (end.Year > DateTime.Today.Year + 100)
|
||||
{
|
||||
isFreezed = false;
|
||||
return;
|
||||
}
|
||||
StartDate = start;
|
||||
EndDate = end;
|
||||
isFreezed = false;
|
||||
OnDateChanged(this);
|
||||
}
|
||||
|
||||
private async void OnFilterCommand(object o)
|
||||
@ -146,6 +331,7 @@ namespace Billing.Views
|
||||
ViewExtensions.CancelAnimations(panelFilter);
|
||||
if (isFilterToggled)
|
||||
{
|
||||
await scroller.ScrollToAsync(scroller.ScrollX, scroller.ScrollY, false);
|
||||
await Task.WhenAll(
|
||||
gridFilter.TranslateTo(0, 0, easing: Easing.CubicOut),
|
||||
gridFilter.FadeTo(1, easing: Easing.CubicOut),
|
||||
@ -179,18 +365,9 @@ namespace Billing.Views
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateBill(UIBill bill)
|
||||
{
|
||||
bill.Icon = App.Categories.FirstOrDefault(c => c.Id == bill.Bill.CategoryId)?.Icon ?? BaseModel.ICON_DEFAULT;
|
||||
bill.Name = bill.Bill.Name;
|
||||
bill.DateCreation = bill.Bill.CreateTime;
|
||||
bill.Amount = bill.Bill.Amount;
|
||||
bill.Wallet = App.Accounts.FirstOrDefault(a => a.Id == bill.Bill.WalletId)?.Name;
|
||||
}
|
||||
|
||||
private async void RefreshBalance()
|
||||
private async void RefreshBalance(DateTime start, DateTime end)
|
||||
{
|
||||
var bills = await Task.Run(() => App.Bills.Where(b => b.CreateTime >= current && b.CreateTime <= end));
|
||||
var bills = await Task.Run(() => App.Bills.Where(b => b.CreateTime >= start && b.CreateTime <= end));
|
||||
var income = bills.Where(b => b.Amount > 0).Sum(b => b.Amount);
|
||||
var spending = -bills.Where(b => b.Amount < 0).Sum(b => b.Amount);
|
||||
SetValue(IncomeProperty, income);
|
||||
@ -198,43 +375,33 @@ namespace Billing.Views
|
||||
SetValue(BalanceProperty, income - spending);
|
||||
}
|
||||
|
||||
private void OnBillChecked(object sender, Bill e)
|
||||
private async void OnBillChecked(object sender, Bill e)
|
||||
{
|
||||
var bill = TopBills.FirstOrDefault(b => b.Bill == e);
|
||||
if (bill != null)
|
||||
{
|
||||
UpdateBill(bill);
|
||||
}
|
||||
RefreshBalance();
|
||||
|
||||
Task.Run(App.WriteBills);
|
||||
await Task.Run(App.WriteBills);
|
||||
LoadData();
|
||||
}
|
||||
|
||||
private async void SetMonth(DateTime date)
|
||||
private async void LoadData()
|
||||
{
|
||||
current = date.AddDays(1 - date.Day);
|
||||
end = current.AddDays(DateTime.DaysInMonth(current.Year, current.Month));
|
||||
|
||||
var format = Resource.DateRangeFormat;
|
||||
Title = current.ToString(format) + " ~ " + end.AddDays(-1).ToString(format);
|
||||
|
||||
var start = StartDate;
|
||||
var end = EndDate;
|
||||
var spending = type == CategoryType.Spending;
|
||||
bills = await Task.Run(() => App.Bills.Where(b => (b.Amount > 0 ^ spending) && b.CreateTime >= current && b.CreateTime <= end));
|
||||
bills = await Task.Run(() => App.Bills.Where(b => (b.Amount > 0 ^ spending) && b.CreateTime >= start && b.CreateTime <= end));
|
||||
|
||||
var primaryColor = BaseTheme.CurrentPrimaryColor.ToSKColor();
|
||||
var textColor = BaseTheme.CurrentSecondaryTextColor.ToSKColor();
|
||||
|
||||
_ = Task.Run(() => LoadReportChart(primaryColor, textColor));
|
||||
_ = Task.Run(() => LoadReportChart(primaryColor, textColor, start, end));
|
||||
_ = Task.Run(() => LoadCategoryChart(primaryColor, textColor));
|
||||
_ = Task.Run(LoadTopBills);
|
||||
|
||||
RefreshBalance();
|
||||
RefreshBalance(start, end);
|
||||
}
|
||||
|
||||
private void LoadReportChart(SKColor primaryColor, SKColor textColor)
|
||||
private void LoadReportChart(SKColor primaryColor, SKColor textColor, DateTime start, DateTime end)
|
||||
{
|
||||
var entries = new List<ChartEntry>();
|
||||
for (var day = current; day <= end; day = day.AddDays(1))
|
||||
for (var day = start; day <= end; day = day.AddDays(1))
|
||||
{
|
||||
var daybills = bills.Where(b => Helper.IsSameDay(b.CreateTime, day));
|
||||
decimal amount = Math.Abs(daybills.Sum(b => b.Amount));
|
||||
@ -350,5 +517,13 @@ namespace Billing.Views
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void Scroller_Scrolled(object sender, ScrolledEventArgs e)
|
||||
{
|
||||
if (isFilterToggled)
|
||||
{
|
||||
OnFilterCommand(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -31,7 +31,7 @@
|
||||
<!--<Label Text="" LineBreakMode="TailTruncation"
|
||||
VerticalOptions="Center"
|
||||
TextColor="{DynamicResource TextColor}"/>-->
|
||||
<ui:ColorPicker Grid.Column="1" ColorChanged="ColorPicker_ColorChanged"/>
|
||||
<ui:ColorPicker Grid.Column="1" Command="{Binding ColorPickerCommand}"/>
|
||||
</Grid>
|
||||
</ViewCell>
|
||||
</TableSection>
|
||||
|
@ -1,6 +1,5 @@
|
||||
using Billing.Themes;
|
||||
using Billing.UI;
|
||||
using System.Globalization;
|
||||
using Xamarin.Essentials;
|
||||
using Xamarin.Forms;
|
||||
|
||||
@ -8,8 +7,8 @@ namespace Billing.Views
|
||||
{
|
||||
public partial class SettingPage : BillingPage
|
||||
{
|
||||
private static readonly BindableProperty VersionProperty = BindableProperty.Create(nameof(Version), typeof(string), typeof(SettingPage));
|
||||
private static readonly BindableProperty PrimaryColorProperty = BindableProperty.Create(nameof(PrimaryColor), typeof(string), typeof(SettingPage));
|
||||
private static readonly BindableProperty VersionProperty = Helper.Create<string, SettingPage>(nameof(Version));
|
||||
private static readonly BindableProperty PrimaryColorProperty = Helper.Create<string, SettingPage>(nameof(PrimaryColor));
|
||||
|
||||
public string Version => (string)GetValue(VersionProperty);
|
||||
public string PrimaryColor
|
||||
@ -19,10 +18,12 @@ namespace Billing.Views
|
||||
}
|
||||
|
||||
public Command CategoryCommand { get; }
|
||||
public Command ColorPickerCommand { get; }
|
||||
|
||||
public SettingPage()
|
||||
{
|
||||
CategoryCommand = new Command(OnCategoryCommand);
|
||||
ColorPickerCommand = new Command(OnColorPickerCommand);
|
||||
InitializeComponent();
|
||||
|
||||
var (main, build) = Definition.GetVersion();
|
||||
@ -60,9 +61,12 @@ namespace Billing.Views
|
||||
}
|
||||
}
|
||||
|
||||
private void ColorPicker_ColorChanged(object sender, Color e)
|
||||
private void OnColorPickerCommand(object o)
|
||||
{
|
||||
PrimaryColor = Helper.WrapColorString(e.ToHex());
|
||||
if (o is Color color)
|
||||
{
|
||||
PrimaryColor = Helper.WrapColorString(color.ToHex());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -18,7 +18,7 @@ namespace Billing.Droid.Renderers
|
||||
base.OnAttachedToWindow();
|
||||
if (Element is BillingPage page)
|
||||
{
|
||||
page.OnLoaded();
|
||||
page.TriggerLoad();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,10 +18,12 @@ namespace Billing.Droid.Renderers
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
|
||||
if (e.NewElement != null)
|
||||
var control = Control;
|
||||
if (e.NewElement != null && control != null)
|
||||
{
|
||||
var drawable = new ColorDrawable(e.NewElement.BackgroundColor.ToAndroid());
|
||||
Control.SetBackground(drawable);
|
||||
control.SetBackground(drawable);
|
||||
control.Gravity = Android.Views.GravityFlags.CenterHorizontal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ namespace Billing.iOS.Renderers
|
||||
base.ViewDidAppear(animated);
|
||||
if (Element is BillingPage page)
|
||||
{
|
||||
page.OnLoaded();
|
||||
page.TriggerLoad();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,9 +14,10 @@ namespace Billing.iOS.Renderers
|
||||
base.OnElementChanged(e);
|
||||
|
||||
var control = Control;
|
||||
if (control != null)
|
||||
if (e.NewElement != null && control != null)
|
||||
{
|
||||
control.BorderStyle = UITextBorderStyle.None;
|
||||
control.TextAlignment = UITextAlignment.Center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user