You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

194 lines
6.6 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// MainPage.xaml.cs
using System.Collections.ObjectModel;
using Microsoft.Maui.Controls;
namespace MauiApp1;
public partial class MainPage : ContentPage
{
private readonly IFileSystemService _fileService;
public ObservableCollection<FileSystemItem> LeftItems { get; set; } = new();
public ObservableCollection<FileSystemItem> RightItems { get; set; } = new();
public string LeftPath { get; set; } = string.Empty;
public string RightPath { get; set; } = string.Empty;
private string _currentLeftPath;
private string _currentRightPath;
private FileSystemItem? _selectedLeftItem;
private FileSystemItem? _selectedRightItem;
public MainPage(IFileSystemService fileService)
{
InitializeComponent();
_fileService = fileService;
BindingContext = this;
var root = _fileService.GetRootPath();
LoadDirectory(root, true);
LoadDirectory(root, false);
}
private void LoadDirectory(string path, bool isLeft)
{
var items = _fileService.GetDirectoryContents(path).ToList();
if (isLeft)
{
LeftItems.Clear();
foreach (var item in items) LeftItems.Add(item);
_currentLeftPath = path;
LeftPath = path;
}
else
{
RightItems.Clear();
foreach (var item in items) RightItems.Add(item);
_currentRightPath = path;
RightPath = path;
}
}
private void OnLeftSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.CurrentSelection.FirstOrDefault() is FileSystemItem item)
{
// Сохраняем выбор
_selectedLeftItem = item;
// Если это ".." или папка — переходим
if (item.Name == ".." || item.IsDirectory)
{
LoadDirectory(item.FullName, true);
// После перехода — сбрасываем выбор, чтобы не осталось выделения в новой папке
_selectedLeftItem = null;
LeftPanel.SelectedItem = null;
}
// Если это файл — ничего не делаем, оставляем его выделенным
}
}
private void OnRightSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.CurrentSelection.FirstOrDefault() is FileSystemItem item)
{
_selectedRightItem = item;
if (item.Name == ".." || item.IsDirectory)
{
LoadDirectory(item.FullName, false);
_selectedRightItem = null;
RightPanel.SelectedItem = null;
}
}
}
private async void OnCopyClicked(object sender, EventArgs e)
{
await ProcessFileOperation(async (src, destDir) =>
{
if (Directory.Exists(src))
await CopyDirectory(src, Path.Combine(destDir, Path.GetFileName(src)));
else
File.Copy(src, Path.Combine(destDir, Path.GetFileName(src)), overwrite: true);
}, "Copy");
}
private async void OnMoveClicked(object sender, EventArgs e)
{
await ProcessFileOperation((src, destDir) =>
{
var dest = Path.Combine(destDir, Path.GetFileName(src));
if (Directory.Exists(src))
Directory.Move(src, dest);
else
File.Move(src, dest, overwrite: true);
return Task.CompletedTask;
}, "Move");
}
private async void OnDeleteClicked(object sender, EventArgs e)
{
var item = _selectedLeftItem ?? _selectedRightItem;
if (item == null) return;
var confirm = await DisplayAlert("Delete", $"Delete '{item.Name}'?", "Yes", "No");
if (confirm)
{
if (item.IsDirectory)
Directory.Delete(item.FullName, recursive: true);
else
File.Delete(item.FullName);
// Обновляем обе панели (или только ту, откуда удалили)
LoadDirectory(_currentLeftPath, true);
LoadDirectory(_currentRightPath, false);
}
}
private async void OnMkdirClicked(object sender, EventArgs e)
{
var result = await DisplayPromptAsync("New Folder", "Folder name:", "Create", "Cancel");
if (string.IsNullOrWhiteSpace(result)) return;
// Создаём в активной панели (выберем левую, если выделение слева, иначе правую)
string targetPath = (_selectedLeftItem != null || LeftItems.Count > 0) ? _currentLeftPath : _currentRightPath;
string newPath = Path.Combine(targetPath, result.Trim());
if (!Directory.Exists(newPath))
{
Directory.CreateDirectory(newPath);
LoadDirectory(_currentLeftPath, true);
LoadDirectory(_currentRightPath, false);
}
else
{
await DisplayAlert("Error", "Folder already exists.", "OK");
}
}
private void OnExitClicked(object sender, EventArgs e)
{
Application.Current?.Quit();
}
private async Task CopyDirectory(string sourceDir, string targetDir)
{
Directory.CreateDirectory(targetDir);
foreach (var file in Directory.GetFiles(sourceDir))
{
await Task.Run(() => File.Copy(file, Path.Combine(targetDir, Path.GetFileName(file)), overwrite: true));
}
foreach (var dir in Directory.GetDirectories(sourceDir))
{
await CopyDirectory(dir, Path.Combine(targetDir, Path.GetFileName(dir)));
}
}
private async Task ProcessFileOperation(Func<string, string, Task> operation, string actionName)
{
var srcItem = _selectedLeftItem ?? _selectedRightItem;
if (srcItem == null)
{
await DisplayAlert("Error", "Select a file or folder first.", "OK");
return;
}
// Определяем целевую директорию: противоположная панель
string destDir = (srcItem == _selectedLeftItem) ? _currentRightPath : _currentLeftPath;
try
{
await operation(srcItem.FullName, destDir);
// Обновляем обе панели
LoadDirectory(_currentLeftPath, true);
LoadDirectory(_currentRightPath, false);
}
catch (Exception ex)
{
await DisplayAlert("Error", $"{actionName} failed: {ex.Message}", "OK");
}
}
}