private void RegisterEvents() { MyLogger.LogAppended += (log) => { LBstatus.Text = MakeOneLine(log); }; SWautoScroll.Toggled += delegate { EDlog.autoScroll = SWautoScroll.IsToggled; }; BTNclear.Clicked += async delegate { BTNclear.IsEnabled = false; if (await MyLogger.Ask("Do you want to clear all the logs?")) { EDlog.Clear(); MyLogger.Log("All logs cleared."); } BTNclear.IsEnabled = true; }; }
private async Task DownloadFile() { if (fileSelected == null) { await MyLogger.Alert("Please select a cloud folder first"); } else { switch (Device.RuntimePlatform) { case Device.Windows: if (fileSelected.IsFolder) { var picker = new Windows.Storage.Pickers.FolderPicker() { ViewMode = Windows.Storage.Pickers.PickerViewMode.List, SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary }; picker.FileTypeFilter.Clear(); picker.FileTypeFilter.Add("*"); var folder = await picker.PickSingleFolderAsync(); if (folder != null) { var folderToDownload = fileSelected; MyLogger.Log($"Folder downloading...\r\nCloud: {folderToDownload.FullName}\r\nLocal: {folder.Path}"); var downloadedFolder = await fileSelected.DownloadFolderOnWindowsAsync(folder); if (downloadedFolder == null) { MyLogger.Log($"Folder download canceled!\r\nCloud: {folderToDownload.FullName}\r\nLocal: {folder.Path}"); } else { MyLogger.Log($"Folder download succeeded!\r\nCloud: {folderToDownload.FullName}\r\nDownloaded: {downloadedFolder.Path}"); } } MyLogger.Log("All done!"); } else { var picker = new Windows.Storage.Pickers.FolderPicker() { ViewMode = Windows.Storage.Pickers.PickerViewMode.List, SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary }; picker.FileTypeFilter.Clear(); picker.FileTypeFilter.Add("*"); var folder = await picker.PickSingleFolderAsync(); if (folder != null) { var fileToDownload = fileSelected; { try { var existedFile = await folder.GetFileAsync(fileToDownload.Name); MyLogger.Assert(existedFile != null); if (await MyLogger.Ask($"\"{fileToDownload.Name}\" already existed in \"{folder.Path}\", overwrite anyway?")) { await existedFile.DeleteAsync(); } else { goto indexSkip; } } catch (FileNotFoundException) { MyLogger.Log("File not found exception, YA!"); } } var localFile = await folder.CreateFileAsync(fileToDownload.Name); MyLogger.Log($"File downloading...\r\nCloud: {fileToDownload.FullName}\r\nLocal: {localFile.Path}"); await fileSelected.DownloadFileOnWindowsAsync(localFile); indexSkip :; } MyLogger.Log("All done!"); } break; default: await MyLogger.Alert($"File picker currently not supported on {Device.RuntimePlatform} devices."); break; } } }
public FileTransferPage() : base("File Transfer") { MyLogger.TestMethodAdded += (name, task) => { var ti = new MyToolbarItem(name); ti.Clicked += async delegate { await task(); }; this.ToolbarItems.Add(ti); }; { GDmain = new MyGrid(); GDmain.RowDefinitions.Add(new Xamarin.Forms.RowDefinition { Height = new Xamarin.Forms.GridLength(1, Xamarin.Forms.GridUnitType.Auto) }); GDmain.RowDefinitions.Add(new Xamarin.Forms.RowDefinition { Height = new Xamarin.Forms.GridLength(1, Xamarin.Forms.GridUnitType.Star) }); { GDctrl = new MyGrid(); GDctrl.ColumnDefinitions.Add(new Xamarin.Forms.ColumnDefinition { Width = new Xamarin.Forms.GridLength(3, Xamarin.Forms.GridUnitType.Star) }); GDctrl.ColumnDefinitions.Add(new Xamarin.Forms.ColumnDefinition { Width = new Xamarin.Forms.GridLength(1, Xamarin.Forms.GridUnitType.Star) }); GDctrl.ColumnDefinitions.Add(new Xamarin.Forms.ColumnDefinition { Width = new Xamarin.Forms.GridLength(2, Xamarin.Forms.GridUnitType.Star) }); GDctrl.ColumnDefinitions.Add(new Xamarin.Forms.ColumnDefinition { Width = new Xamarin.Forms.GridLength(4, Xamarin.Forms.GridUnitType.Star) }); GDctrl.ColumnDefinitions.Add(new Xamarin.Forms.ColumnDefinition { Width = new Xamarin.Forms.GridLength(1, Xamarin.Forms.GridUnitType.Star) }); GDctrl.ColumnDefinitions.Add(new Xamarin.Forms.ColumnDefinition { Width = new Xamarin.Forms.GridLength(1, Xamarin.Forms.GridUnitType.Star) }); GDctrl.ColumnDefinitions.Add(new Xamarin.Forms.ColumnDefinition { Width = new Xamarin.Forms.GridLength(1, Xamarin.Forms.GridUnitType.Star) }); GDctrl.ColumnDefinitions.Add(new Xamarin.Forms.ColumnDefinition { Width = new Xamarin.Forms.GridLength(1, Xamarin.Forms.GridUnitType.Star) }); GDctrl.ColumnDefinitions.Add(new Xamarin.Forms.ColumnDefinition { Width = new Xamarin.Forms.GridLength(1, Xamarin.Forms.GridUnitType.Star) }); int columnNumber = 0; { var sw = new MySwitch("Auto Restart Failed tasks", "Manual Restart Failed Tasks", false); FTmain = new FileTransferContentView(); sw.Toggled += delegate { FTmain.SetAutoRestartFailedTasks(sw.IsToggled); }; sw.IsToggled = true; GDctrl.Children.Add(sw, columnNumber++, 0); } { var toSpeedText = new Func <long, string>((value) => { double v = value; if (v <= 1023) { return($"{v.ToString("F5").Remove(5).PadRight(5, '0')} B/s"); } v /= 1024; if (v <= 1023) { return($"{v.ToString("F5").Remove(5).PadRight(5, '0')} KB/s"); } v /= 1024; return($"{v.ToString("F5").Remove(5).PadRight(5, '0')} MB/s"); }); var lbl = new MyLabel($"{toSpeedText(0)}") { VerticalTextAlignment = TextAlignment.Center }; System.Threading.SemaphoreSlim semaphoreSlim = new System.Threading.SemaphoreSlim(1, 1); long totalAmountSent = 0; CloudFile.Networker.ChunkProcceeded += async(coda) => { totalAmountSent += coda; DateTime startTime = DateTime.Now; await semaphoreSlim.WaitAsync(); while ((DateTime.Now - startTime).TotalSeconds <= 5) { lbl.Text = $"{toSpeedText(totalAmountSent / 5)}"; await Task.Delay(100); } totalAmountSent -= coda; lbl.Text = toSpeedText(totalAmountSent / 5); lock (semaphoreSlim) semaphoreSlim.Release(); }; GDctrl.Children.Add(lbl, columnNumber++, 0); } { var btn = new MyButton("Reset"); GDctrl.Children.Add(btn, columnNumber++, 0); var lbl = new MyLabel("") { VerticalTextAlignment = TextAlignment.Center }; long totalAmountLeft = 0, totalFilesLeft = 0, totalFoldersLeft = 0; long totalAmount = 0, totalFiles = 0, totalFolders = 0; btn.Clicked += async delegate { btn.IsEnabled = false; if (await MyLogger.Ask("Are you sure to reset the statistic data?\r\nIncluding: total data amount, file count, folder count")) { totalAmount = totalFiles = totalFolders = 0; } btn.IsEnabled = true; }; var toSizeText = new Func <long, string>((value) => { double v = value; if (v <= 1023) { return($"{v.ToString("F5").Remove(5)} B"); } v /= 1024; if (v <= 1023) { return($"{v.ToString("F5").Remove(5)} KB"); } v /= 1024; if (v <= 1023) { return($"{v.ToString("F5").Remove(5)} MB"); } v /= 1024; if (v <= 1023) { return($"{v.ToString("F5").Remove(5)} GB"); } v /= 1024; return($"{v.ToString("F5").Remove(5)} TB"); }); System.Threading.SemaphoreSlim semaphoreSlim = new System.Threading.SemaphoreSlim(1, 1); DateTime lastUpdate = DateTime.MinValue; var showResult = new Func <Task>(async() => { var updateTime = DateTime.Now; await semaphoreSlim.WaitAsync(); if (updateTime <= lastUpdate) { return; } lbl.Text = $"{toSizeText(totalAmountLeft)} / {toSizeText(totalAmount)} \t{totalFilesLeft } / {totalFiles} files \t{totalFoldersLeft } / {totalFolders} folders"; await Task.Delay(100); lock (semaphoreSlim) semaphoreSlim.Release(); }); CloudFile.Networker.TotalAmountRemainChanged += async(coda) => { if (coda < 0) { totalAmount -= coda; } totalAmountLeft += coda; await showResult(); }; CloudFile.Networker.TotalFilesRemainChanged += async(coda) => { if (coda < 0) { totalFiles -= coda; } totalFilesLeft += coda; await showResult(); }; CloudFile.Networker.TotalFoldersRemainChanged += async(coda) => { if (coda < 0) { totalFolders -= coda; } totalFoldersLeft += coda; await showResult(); }; GDctrl.Children.Add(lbl, columnNumber++, 0); } { var actions = new Dictionary <CloudFile.Networker.NetworkStatus, Func <int, Task> >(); foreach (var status in Enum.GetValues(typeof(CloudFile.Networker.NetworkStatus)).Cast <CloudFile.Networker.NetworkStatus>()) { networkers[status] = new HashSet <CloudFile.Networker>(); string text; Func <CloudFile.Networker, Task> clickAction = null; switch (status) { case CloudFile.Networker.NetworkStatus.Completed: text = "\u2714"; break; case CloudFile.Networker.NetworkStatus.ErrorNeedRestart: { text = "\u26a0"; clickAction = new Func <CloudFile.Networker, Task>(async(networker) => { await networker.ResetAsync(); await networker.StartAsync(); }); } break; case CloudFile.Networker.NetworkStatus.Networking: { text = "\u23f8"; clickAction = new Func <CloudFile.Networker, Task>(async(networker) => { await networker.PauseAsync(); }); } break; case CloudFile.Networker.NetworkStatus.NotStarted: { text = "\u23f0"; clickAction = new Func <CloudFile.Networker, Task>(async(networker) => { await networker.StartAsync(); }); } break; case CloudFile.Networker.NetworkStatus.Paused: { text = "\u25b6"; clickAction = new Func <CloudFile.Networker, Task>(async(networker) => { await networker.StartAsync(); }); } break; default: throw new Exception($"status: {status}"); } MyButton btn = new MyButton(text) { Opacity = 0 }; if (status == CloudFile.Networker.NetworkStatus.Completed) { btn.IsEnabled = false; } btn.Clicked += async delegate { IEnumerable <Task> tasks; lock (networkers) { tasks = networkers[status].ToList().Select(async(networker) => { await clickAction(networker); }); } await Task.WhenAll(tasks); }; int number = 0; System.Threading.SemaphoreSlim semaphoreSlim = new System.Threading.SemaphoreSlim(1, 1); DateTime lastUpdate = DateTime.Now; actions[status] = new Func <int, Task>(async(difference) => { bool isZeroBefore = (number == 0); number += difference; DateTime updateTime = DateTime.Now; await semaphoreSlim.WaitAsync(); try { if (updateTime <= lastUpdate) { return; } lastUpdate = updateTime; btn.Text = $"{text}{number}"; if (number == 0 && !isZeroBefore) { await btn.FadeTo(0, 500); } if (number != 0 && isZeroBefore) { await btn.FadeTo(1, 500); } await Task.Delay(100); } finally { lock (semaphoreSlim) semaphoreSlim.Release(); } }); GDctrl.Children.Add(btn, columnNumber++, 0); } FTmain.StatusEnter += async(networker, status) => { networkers[status].Add(networker); await actions[status](1); }; FTmain.StatusLeave += async(networker, status) => { networkers[status].Remove(networker); await actions[status](-1); }; } GDmain.Children.Add(GDctrl, 0, 0); } { GDmain.Children.Add(new Frame { OutlineColor = Color.Accent, Padding = new Thickness(5), Content = FTmain }, 0, 1); } this.Content = GDmain; } }