feat:基础功能实现

feat: 重构 TodoList 架构,新增动态 API 与 MAUI 内嵌 Web 服务
feat:优化交互逻辑,优化发布流程
This commit is contained in:
ShaoHua
2026-04-05 00:53:18 +08:00
parent ed3d90cd7a
commit ceb77e624e
147 changed files with 24036 additions and 206 deletions
+63 -7
View File
@@ -7,16 +7,19 @@ using TodoList.Services;
using TodoList.ViewModels;
using TodoList.Views;
using System.Linq;
using System.Reflection;
namespace TodoList
{
public partial class App : System.Windows.Application
{
private const string MainWindowTitle = "待办事项";
private IDataService _dataService;
private GlobalShortcutService _shortcutService;
private MainWindow _mainWindow;
private QuickEntryWindow? _quickEntryWindow;
private SettingsService _settingsService;
private System.Windows.Forms.NotifyIcon _notifyIcon;
private NotifyIcon _notifyIcon;
private Mutex _mutex;
private EventWaitHandle _eventWaitHandle;
private const string UniqueEventName = "Global\\TodoListApp_Event_v1";
@@ -59,7 +62,7 @@ namespace TodoList
catch
{
// Fallback to old method if event open fails
var hWnd = FindWindow(null, "待办事项");
var hWnd = FindWindow(null, MainWindowTitle);
if (hWnd != IntPtr.Zero)
{
ShowWindow(hWnd, 9); // SW_RESTORE
@@ -107,6 +110,7 @@ namespace TodoList
var mainViewModel = new MainViewModel(_dataService, _settingsService);
_mainWindow = new MainWindow(mainViewModel);
_mainWindow.Title = MainWindowTitle;
_mainWindow.Loaded += MainWindow_Loaded;
// Initialize Tray Icon
@@ -131,7 +135,7 @@ namespace TodoList
{
try
{
var exePath = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
var exePath = System.Diagnostics.Process.GetCurrentProcess().MainModule?.FileName;
string cmd = $"\"{exePath}\" --silent";
// If running as dotnet tool, try to find the shim or stable entry point
@@ -167,7 +171,7 @@ namespace TodoList
private void InitializeTrayIcon()
{
_notifyIcon = new System.Windows.Forms.NotifyIcon();
_notifyIcon = new NotifyIcon();
// Try load icon from resource or file
try
@@ -194,15 +198,43 @@ namespace TodoList
}
_notifyIcon.Visible = true;
_notifyIcon.Text = "TodoList";
_notifyIcon.Text = GetNotifyIconText();
_notifyIcon.DoubleClick += (s, e) => ShowMainWindow();
var contextMenu = new System.Windows.Forms.ContextMenuStrip();
var contextMenu = new ContextMenuStrip();
contextMenu.Items.Add("打开主界面", null, (s, e) => ShowMainWindow());
contextMenu.Items.Add("退出", null, (s, e) => ExitApplication());
_notifyIcon.ContextMenuStrip = contextMenu;
}
private static string GetNotifyIconText()
{
var version = GetDisplayVersion();
var text = string.IsNullOrWhiteSpace(version) ? MainWindowTitle : $"{MainWindowTitle} v{version}";
return text.Length > 63 ? text[..63] : text;
}
private static string? GetDisplayVersion()
{
var asm = Assembly.GetExecutingAssembly();
var info = asm.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion?.Trim();
if (!string.IsNullOrWhiteSpace(info))
{
var plus = info.IndexOf('+');
return plus >= 0 ? info[..plus] : info;
}
var file = asm.GetCustomAttribute<AssemblyFileVersionAttribute>()?.Version?.Trim();
if (!string.IsNullOrWhiteSpace(file))
{
return file;
}
return asm.GetName().Version?.ToString();
}
private void ShowMainWindow()
{
Log("ShowMainWindow called");
@@ -289,7 +321,31 @@ namespace TodoList
private void OnHotKeyPressed()
{
Log("Hotkey pressed.");
ShowMainWindow();
ShowQuickEntryWindow();
}
private void ShowQuickEntryWindow()
{
if (_quickEntryWindow == null)
{
_quickEntryWindow = new QuickEntryWindow(_dataService);
_quickEntryWindow.Title = "新建待办";
}
if (_quickEntryWindow.WindowState == WindowState.Minimized)
{
_quickEntryWindow.WindowState = WindowState.Normal;
}
_quickEntryWindow.Show();
_quickEntryWindow.Activate();
var helper = new WindowInteropHelper(_quickEntryWindow);
var handle = helper.Handle;
if (handle != IntPtr.Zero)
{
SetForegroundWindow(handle);
}
}
protected override void OnExit(ExitEventArgs e)