using CommunityToolkit.Maui.Views;
using NotesDataAnalyst.NoteContent;
using System.Text.RegularExpressions;
using System.Windows.Input;
namespace NotesDataAnalyst
{
public partial class EditorPage : ContentPage
{
//Вызываем эмодзи
public ICommand ShowEmojiPopupCommand { get; }
public ICommand ShowLinkInputCommand { get; }
public ICommand InsertHeaderCommand { get; }
public ICommand AddLinkCommand { get; }
private int listItemCounter = 1; // Счётчик для нумерации в списке
private readonly Note _note;
private readonly FileSaver _fileSaver;
private readonly string _filePath;
public EditorPage(Note note = null)
{
InitializeComponent();
// Инициализация команд
// Инициализация команд
InsertHeaderCommand = new Command(InsertHeaderTag);
// InsertBulletCommand = new Command(InsertBulletPoint);
AddLinkCommand = new Command(AddLink);
// InsertNumberedListCommand = new Command(InsertNumberedListItem);
ShowLinkInputCommand = new Command(ShowLinkInputPopup);
//Иницилизируем эмодзи
ShowEmojiPopupCommand = new Command(ShowEmojiSelectionPopup);
BindingContext = this; // Устанавливаем контекст привязки на текущий объект страницы
_note = note ?? new Note(); // Если note не передан, создаём новую заметку
_filePath = string.Empty; // Пустой путь указывает на создание новой заметки
// Заполняем данные, если это существующая заметка
if (_note != null)
{
categoryPicker.SelectedItem = _note.Category;
titleEditor.Text = _note.Title;
textEditor.Text = _note.Text;
if (!string.IsNullOrEmpty(_note.Image))
{
imageButton.Source = ImageSource.FromFile(_note.Image);
}
}
// Настраиваем выбор категории и установку фокуса
CategoryManager.LoadCategories();
categoryPicker.ItemsSource = CategoryManager.Categories;
categoryPicker.SelectedItem = CategoryManager.ActiveCategory;
string basePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Notes");
_fileSaver = new FileSaver(basePath);
}
// Работаем с эмодзи
private async void ShowEmojiSelectionPopup()
{
var emojiPopup = new EmojiSelectionPopup();
// Обработчик выбора смайлика
emojiPopup.EmojiSelected += emoji =>
{
InsertEmoji(emoji);
// Используем Dispatcher для безопасного вызова Close
Application.Current.Dispatcher.Dispatch(() =>
{
if (emojiPopup.Handler != null) // Проверка, что Popup еще не закрыт
{
emojiPopup.Close();
}
});
};
// Отображаем Popup
await Application.Current.MainPage.ShowPopupAsync(emojiPopup);
}
private void InsertEmoji(string emoji)
{
int cursorPosition = textEditor.CursorPosition;
textEditor.Text = textEditor.Text.Insert(cursorPosition, emoji);
textEditor.CursorPosition = cursorPosition + emoji.Length;
}
///////////////////////
///
///
/// //////////////////////////////////////////////////////////////
///
///
// Тэги маркдаун
private void InsertHeaderTag()
{
if (textEditor == null)
{
Console.WriteLine("textEditor не инициализирован.");
return;
}
// Проверка, если текст пустой
if (string.IsNullOrEmpty(textEditor.Text))
{
textEditor.Text = "# ";
textEditor.CursorPosition = textEditor.Text.Length;
return;
}
int cursorPosition = textEditor.CursorPosition;
string newText = cursorPosition == 0 || textEditor.Text[cursorPosition - 1] == '\n' ? "# " : "\n# ";
textEditor.Text = textEditor.Text.Insert(cursorPosition, newText);
textEditor.CursorPosition = cursorPosition + newText.Length;
}
private async void ShowLinkInputPopup()
{
var linkInputPopup = new LinkInputPopup();
// Подписываемся на событие, чтобы получить ссылку и вставить её в текст
linkInputPopup.LinkSubmitted += url =>
{
InsertLinkMarkdown(url);
};
// Открываем модально
await Application.Current.MainPage.Navigation.PushModalAsync(linkInputPopup);
}
private void InsertLinkMarkdown(string url)
{
string markdownLink = $"";
int cursorPosition = textEditor.CursorPosition;
textEditor.Text = textEditor.Text.Insert(cursorPosition, markdownLink);
textEditor.CursorPosition = cursorPosition + markdownLink.Length;
}
/* private void InsertBulletPoint()
{
if (textEditor == null)
{
Console.WriteLine("textEditor не инициализирован.");
return;
}
if (string.IsNullOrEmpty(textEditor.Text))
{
textEditor.Text = "* ";
textEditor.CursorPosition = textEditor.Text.Length;
return;
}
int cursorPosition = textEditor.CursorPosition;
string bulletText = "* ";
textEditor.Text = textEditor.Text.Insert(cursorPosition, bulletText);
textEditor.CursorPosition = cursorPosition + bulletText.Length;
textEditor.Completed += (s, e) =>
{
if (!HasTwoEmptyLines(cursorPosition))
{
cursorPosition = textEditor.CursorPosition;
textEditor.Text = textEditor.Text.Insert(cursorPosition, bulletText);
textEditor.CursorPosition = cursorPosition + bulletText.Length;
}
};
}
private void InsertNumberedListItem()
{
int cursorPosition = textEditor.CursorPosition;
string listItemText = $"{listItemCounter}. ";
textEditor.Text = textEditor.Text.Insert(cursorPosition, listItemText);
textEditor.CursorPosition = cursorPosition + listItemText.Length;
// Обновляем номер списка при переходе на новую строку
textEditor.Completed += (s, e) =>
{
if (!HasTwoEmptyLines(cursorPosition))
{
cursorPosition = textEditor.CursorPosition;
listItemCounter++;
listItemText = $"{listItemCounter}. ";
textEditor.Text = textEditor.Text.Insert(cursorPosition, listItemText);
textEditor.CursorPosition = cursorPosition + listItemText.Length;
}
else
{
listItemCounter = 1; // Сброс счётчика при двух пустых строках
}
};
}
// Проверка на две пустые строки после позиции курсора
private bool HasTwoEmptyLines(int position)
{
string textAfterCursor = textEditor.Text.Substring(position);
return Regex.IsMatch(textAfterCursor, @"\n\s*\n\s*\n");
}*/
////////////////////////////////////////////////////////////////////////////////////////////
private async void AddLink()
{
var popup = new NoteSelectionPopup();
popup.NoteSelected += OnNoteSelectedForLink;
await this.ShowPopupAsync(popup);
}
private void OnNoteSelectedForLink(Note selectedNote)
{
textEditor.Text = NoteLinkManager.InsertLink(textEditor.Text, selectedNote);
}
private async void OnImageTapped(object sender, EventArgs e)
{
try
{
var result = await FilePicker.PickAsync(new PickOptions
{
FileTypes = FilePickerFileType.Images,
PickerTitle = "Выберите изображение"
});
if (result != null)
{
_note.Image = result.FullPath;
imageButton.Source = ImageSource.FromFile(result.FullPath);
}
}
catch (Exception ex)
{
await DisplayAlert("Ошибка", $"Не удалось загрузить изображение: {ex.Message}", "OK");
}
}
private async void SaveButton_Clicked(object sender, EventArgs e)
{
// Если у заметки нет Id, присваиваем новый Id
if (string.IsNullOrEmpty(_note.Id))
{
_note.Id = Guid.NewGuid().ToString();
}
var note = new Note
{ Id = _note.Id,
Category = categoryPicker.SelectedItem as string,
Title = titleEditor.Text,
Image = _note.Image,
Text = textEditor.Text,
FilePath = _filePath
};
// Проверка заголовка
if (string.IsNullOrEmpty(note.Title))
{
// Получаем первые 4 слова из текста
var words = note.Text.Split(' ', StringSplitOptions.RemoveEmptyEntries);
note.Title = string.Join(" ", words.Take(4));
}
//Запись в БД пока отключена
await Task.Run(() => App.Database.SaveNote(note));
// Отправляем сообщение для обновления списка заметок на главной странице
MessagingCenter.Send(this, "NoteSaved", _note);
await DisplayAlert("Success", "Note saved successfully.", "OK");
await Navigation.PushAsync(new MainPage());
}
}
}