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