This commit is contained in:
gaoyuan
2022-03-11 22:25:31 +08:00
parent 6d2e0624ab
commit 51ac42b9fc
14 changed files with 134 additions and 19 deletions

View File

@ -1,9 +1,12 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using Billing.Languages; using Billing.Languages;
using Billing.Models; using Billing.Models;
using Billing.Store; using Billing.Store;
using Billing.Themes; using Billing.Themes;
using Billing.UI;
using Xamarin.Essentials; using Xamarin.Essentials;
using Xamarin.Forms; using Xamarin.Forms;
@ -27,7 +30,7 @@ namespace Billing
InitResources(); InitResources();
MainPage = new MainShell(); MainPage = new MainShell();
Shell.Current.GoToAsync("//Splash"); //Shell.Current.GoToAsync("//Splash");
} }
protected override void OnStart() protected override void OnStart()
@ -36,7 +39,7 @@ namespace Billing
Helper.Debug($"cache folder: {StoreHelper.CacheFolder}"); Helper.Debug($"cache folder: {StoreHelper.CacheFolder}");
} }
internal static async Task InitilalizeData() internal static async Task InitializeData()
{ {
await Task.WhenAll( await Task.WhenAll(
Task.Run(async () => accounts = await StoreHelper.GetAccountsAsync()), Task.Run(async () => accounts = await StoreHelper.GetAccountsAsync()),
@ -79,5 +82,33 @@ namespace Billing
// TODO: status bar // TODO: status bar
Resources = instance; Resources = instance;
} }
public static bool OpenUrl(Uri uri)
{
if (uri == null)
{
return true;
}
var absolute = uri.AbsolutePath;
var url = System.Net.WebUtility.UrlDecode(absolute);
if (File.Exists(url))
{
Task.Run(async () =>
{
var result = await StoreHelper.ReloadDatabase(url);
//if (result)
{
await InitializeData();
var current = Shell.Current.CurrentPage;
if (current is BillingPage page)
{
MainThread.BeginInvokeOnMainThread(() => page.TriggerRefresh());
}
}
});
}
return true;
}
} }
} }

View File

@ -10,15 +10,14 @@
TitleColor="{DynamicResource PrimaryColor}" TitleColor="{DynamicResource PrimaryColor}"
Shell.NavBarHasShadow="True"> Shell.NavBarHasShadow="True">
<FlyoutItem>
<ShellContent ContentTemplate="{DataTemplate local:SplashPage}" Route="Splash"/>
</FlyoutItem>
<TabBar> <TabBar>
<ShellContent ContentTemplate="{DataTemplate v:AccountPage}" Route="Accounts" Title="{r:Text Accounts}" Icon="wallet.png"/> <ShellContent ContentTemplate="{DataTemplate v:AccountPage}" Route="Accounts" Title="{r:Text Accounts}" Icon="wallet.png"/>
<ShellContent ContentTemplate="{DataTemplate v:BillPage}" Route="Bills" Title="{r:Text Bills}" Icon="bill.png"/> <ShellContent ContentTemplate="{DataTemplate v:BillPage}" Route="Bills" Title="{r:Text Bills}" Icon="bill.png"/>
<ShellContent ContentTemplate="{DataTemplate v:RankPage}" Route="Ranks" Title="{r:Text Report}" Icon="rank.png"/> <ShellContent ContentTemplate="{DataTemplate v:RankPage}" Route="Ranks" Title="{r:Text Report}" Icon="rank.png"/>
<ShellContent ContentTemplate="{DataTemplate v:SettingPage}" Route="Settings" Title="{r:Text Settings}" Icon="settings.png"/> <ShellContent ContentTemplate="{DataTemplate v:SettingPage}" Route="Settings" Title="{r:Text Settings}" Icon="settings.png"/>
</TabBar> </TabBar>
<Tab>
<ShellContent ContentTemplate="{DataTemplate local:SplashPage}" Route="Splash"/>
</Tab>
</Shell> </Shell>

View File

@ -10,9 +10,9 @@ namespace Billing
InitializeComponent(); InitializeComponent();
} }
public override async void OnLoaded() protected override async void OnLoaded()
{ {
await App.InitilalizeData(); await App.InitializeData();
await Shell.Current.GoToAsync("//Bills"); await Shell.Current.GoToAsync("//Bills");
} }

View File

@ -14,11 +14,32 @@ namespace Billing.Store
public static readonly string PersonalFolder = Environment.GetFolderPath(Environment.SpecialFolder.Personal); public static readonly string PersonalFolder = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
public static readonly string CacheFolder = FileSystem.CacheDirectory; public static readonly string CacheFolder = FileSystem.CacheDirectory;
public static string DatabasePath => Path.Combine(PersonalFolder, dbfile);
#region Sqlite3 #region Sqlite3
private const string dbfile = "data.db3"; private const string dbfile = "data.db3";
private static SQLiteAsyncConnection database; private static SQLiteAsyncConnection database;
#endregion #endregion
public static async Task<bool> ReloadDatabase(string file)
{
var path = DatabasePath;
if (string.Equals(file, path, StringComparison.OrdinalIgnoreCase))
{
return false;
}
if (database != null)
{
await database.CloseAsync();
}
File.Copy(file, path, true);
database = new SQLiteAsyncConnection(path,
SQLiteOpenFlags.ReadWrite |
SQLiteOpenFlags.Create |
SQLiteOpenFlags.SharedCache);
return true;
}
private static readonly AsyncLazy<StoreHelper> Instance = new(async () => private static readonly AsyncLazy<StoreHelper> Instance = new(async () =>
{ {
var instance = new StoreHelper(); var instance = new StoreHelper();
@ -114,10 +135,13 @@ namespace Billing.Store
private StoreHelper() private StoreHelper()
{ {
database = new SQLiteAsyncConnection(Path.Combine(PersonalFolder, dbfile), if (database == null)
SQLiteOpenFlags.ReadWrite | {
SQLiteOpenFlags.Create | database = new SQLiteAsyncConnection(DatabasePath,
SQLiteOpenFlags.SharedCache); SQLiteOpenFlags.ReadWrite |
SQLiteOpenFlags.Create |
SQLiteOpenFlags.SharedCache);
}
} }
public Task<List<T>> GetListAsync<T>(string query, params object[] args) where T : new() public Task<List<T>> GetListAsync<T>(string query, params object[] args) where T : new()

View File

@ -7,6 +7,7 @@ namespace Billing.UI
public abstract class BillingPage : ContentPage public abstract class BillingPage : ContentPage
{ {
public event EventHandler Loaded; public event EventHandler Loaded;
public event EventHandler Refreshed;
private bool loaded; private bool loaded;
@ -16,11 +17,16 @@ namespace Billing.UI
Shell.SetTabBarIsVisible(this, false); Shell.SetTabBarIsVisible(this, false);
} }
public virtual void OnLoaded() protected virtual void OnLoaded()
{ {
Loaded?.Invoke(this, EventArgs.Empty); Loaded?.Invoke(this, EventArgs.Empty);
} }
protected virtual void OnRefresh()
{
Refreshed?.Invoke(this, EventArgs.Empty);
}
public void TriggerLoad() public void TriggerLoad()
{ {
if (!loaded) if (!loaded)
@ -29,5 +35,10 @@ namespace Billing.UI
OnLoaded(); OnLoaded();
} }
} }
public void TriggerRefresh()
{
OnRefresh();
}
} }
} }

View File

@ -73,7 +73,7 @@ namespace Billing.Views
InitializeComponent(); InitializeComponent();
} }
public override void OnLoaded() protected override void OnLoaded()
{ {
editorName.SetFocus(); editorName.SetFocus();
} }

View File

@ -116,7 +116,7 @@ namespace Billing.Views
} }
} }
public override void OnLoaded() protected override void OnLoaded()
{ {
editorAmount.SetFocus(); editorAmount.SetFocus();
} }

View File

@ -78,7 +78,7 @@ namespace Billing.Views
InitializeComponent(); InitializeComponent();
} }
public override void OnLoaded() protected override void OnLoaded()
{ {
editorName.SetFocus(); editorName.SetFocus();
} }

View File

@ -55,7 +55,7 @@ namespace Billing.Views
InitializeComponent(); InitializeComponent();
} }
public override void OnLoaded() protected override void OnLoaded()
{ {
billingDate.SetDateTime(DateTime.Today); billingDate.SetDateTime(DateTime.Today);
} }

View File

@ -11,6 +11,10 @@
BindingContext="{x:Reference settingPage}" BindingContext="{x:Reference settingPage}"
Shell.TabBarIsVisible="True"> Shell.TabBarIsVisible="True">
<ContentPage.ToolbarItems>
<ToolbarItem Order="Primary" IconImageSource="project.png" Command="{Binding ShareCommand}"/>
</ContentPage.ToolbarItems>
<TableView Intent="Settings" HasUnevenRows="True"> <TableView Intent="Settings" HasUnevenRows="True">
<TableSection Title="{r:Text About}"> <TableSection Title="{r:Text About}">
<ui:OptionTextCell Height="36" Title="{r:Text Version}" <ui:OptionTextCell Height="36" Title="{r:Text Version}"

View File

@ -1,3 +1,4 @@
using Billing.Store;
using Billing.Themes; using Billing.Themes;
using Billing.UI; using Billing.UI;
using Xamarin.Essentials; using Xamarin.Essentials;
@ -17,11 +18,13 @@ namespace Billing.Views
set => SetValue(PrimaryColorProperty, value); set => SetValue(PrimaryColorProperty, value);
} }
public Command ShareCommand { get; }
public Command CategoryCommand { get; } public Command CategoryCommand { get; }
public Command ColorPickerCommand { get; } public Command ColorPickerCommand { get; }
public SettingPage() public SettingPage()
{ {
ShareCommand = new Command(OnShareCommand);
CategoryCommand = new Command(OnCategoryCommand); CategoryCommand = new Command(OnCategoryCommand);
ColorPickerCommand = new Command(OnColorPickerCommand); ColorPickerCommand = new Command(OnColorPickerCommand);
InitializeComponent(); InitializeComponent();
@ -48,6 +51,21 @@ namespace Billing.Views
Light.Instance.RefreshColor(Color.FromHex(color)); Light.Instance.RefreshColor(Color.FromHex(color));
} }
private async void OnShareCommand()
{
if (Tap.IsBusy)
{
return;
}
using (Tap.Start())
{
await Share.RequestAsync(new ShareFileRequest
{
File = new ShareFile(StoreHelper.DatabasePath)
});
}
}
private async void OnCategoryCommand() private async void OnCategoryCommand()
{ {
if (Tap.IsBusy) if (Tap.IsBusy)

View File

@ -23,5 +23,10 @@ namespace Billing.iOS
return base.FinishedLaunching(app, options); return base.FinishedLaunching(app, options);
} }
public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
{
return App.OpenUrl(url);
}
} }
} }

View File

@ -477,6 +477,14 @@
<ItemGroup> <ItemGroup>
<BundleResource Include="Resources\left%403x.png" /> <BundleResource Include="Resources\left%403x.png" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Billing.ShareExtension\Billing.ShareExtension.csproj">
<IsAppExtension>true</IsAppExtension>
<Project>{D4EA6D3A-17E6-4300-80A7-2ED19B738C6B}</Project>
<Name>Billing.ShareExtension</Name>
<ReferenceSourceTarget></ReferenceSourceTarget>
</ProjectReference>
</ItemGroup>
<Import Project="..\..\Billing.Shared\Billing.Shared.projitems" Label="Shared" /> <Import Project="..\..\Billing.Shared\Billing.Shared.projitems" Label="Shared" />
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" /> <Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
</Project> </Project>

View File

@ -41,6 +41,21 @@
<string>OpenSans-Regular.ttf</string> <string>OpenSans-Regular.ttf</string>
<string>OpenSans-SemiBold.ttf</string> <string>OpenSans-SemiBold.ttf</string>
</array> </array>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>Master SQLite file</string>
<key>LSItemContentTypes</key>
<array>
<string>public.data</string>
</array>
<key>CFBundleTypeIconFiles</key>
<array>
<string>Assets.xcassets/AppIcon.appiconset/Icon180</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>10</string> <string>10</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>