diff --git a/lib/collections/fonts.gen.dart b/lib/collections/fonts.gen.dart index 033d3a79..c51dfd40 100644 --- a/lib/collections/fonts.gen.dart +++ b/lib/collections/fonts.gen.dart @@ -13,6 +13,9 @@ class FontFamily { /// Font family: BootstrapIcons static const String bootstrapIcons = 'BootstrapIcons'; + /// Font family: Cookie + static const String cookie = 'Cookie'; + /// Font family: RadixIcons static const String radixIcons = 'RadixIcons'; } diff --git a/lib/collections/initializers.dart b/lib/collections/initializers.dart index 976661fc..5df3e67e 100644 --- a/lib/collections/initializers.dart +++ b/lib/collections/initializers.dart @@ -1,26 +1,3 @@ -import 'dart:io'; - -import 'package:spotube/utils/platform.dart'; -import 'package:win32_registry/win32_registry.dart'; - -Future registerWindowsScheme(String scheme) async { - if (!kIsWindows) return; - String appPath = Platform.resolvedExecutable; - - String protocolRegKey = 'Software\\Classes\\$scheme'; - RegistryValue protocolRegValue = const RegistryValue( - 'URL Protocol', - RegistryValueType.string, - '', - ); - String protocolCmdRegKey = 'shell\\open\\command'; - RegistryValue protocolCmdRegValue = RegistryValue( - '', - RegistryValueType.string, - '"$appPath" "%1"', - ); - - final regKey = Registry.currentUser.createKey(protocolRegKey); - regKey.createValue(protocolRegValue); - regKey.createKey(protocolCmdRegKey).createValue(protocolCmdRegValue); -} +// Conditional exports for platform initializers +export 'initializers_native.dart' + if (dart.library.html) 'initializers_web.dart'; \ No newline at end of file diff --git a/lib/collections/initializers_native.dart b/lib/collections/initializers_native.dart new file mode 100644 index 00000000..976661fc --- /dev/null +++ b/lib/collections/initializers_native.dart @@ -0,0 +1,26 @@ +import 'dart:io'; + +import 'package:spotube/utils/platform.dart'; +import 'package:win32_registry/win32_registry.dart'; + +Future registerWindowsScheme(String scheme) async { + if (!kIsWindows) return; + String appPath = Platform.resolvedExecutable; + + String protocolRegKey = 'Software\\Classes\\$scheme'; + RegistryValue protocolRegValue = const RegistryValue( + 'URL Protocol', + RegistryValueType.string, + '', + ); + String protocolCmdRegKey = 'shell\\open\\command'; + RegistryValue protocolCmdRegValue = RegistryValue( + '', + RegistryValueType.string, + '"$appPath" "%1"', + ); + + final regKey = Registry.currentUser.createKey(protocolRegKey); + regKey.createValue(protocolRegValue); + regKey.createKey(protocolCmdRegKey).createValue(protocolCmdRegValue); +} diff --git a/lib/collections/initializers_web.dart b/lib/collections/initializers_web.dart new file mode 100644 index 00000000..dca0d994 --- /dev/null +++ b/lib/collections/initializers_web.dart @@ -0,0 +1,4 @@ +// Web implementation - no Windows registry needed +Future registerWindowsScheme(String scheme) async { + // Web doesn't support custom URL schemes registration +} \ No newline at end of file diff --git a/lib/services/wm_tools/wm_tools.dart b/lib/services/wm_tools/wm_tools.dart index f60b4ac9..465cc24f 100644 --- a/lib/services/wm_tools/wm_tools.dart +++ b/lib/services/wm_tools/wm_tools.dart @@ -1,89 +1,3 @@ -import 'package:shadcn_flutter/shadcn_flutter.dart'; -import 'package:spotube/services/kv_store/kv_store.dart'; -import 'package:spotube/utils/platform.dart'; -import 'package:window_manager/window_manager.dart'; - -class WindowSize { - final double height; - final double width; - final bool maximized; - - WindowSize({ - required this.height, - required this.width, - required this.maximized, - }); - - factory WindowSize.fromJson(Map json) => WindowSize( - height: json["height"], - width: json["width"], - maximized: json["maximized"], - ); - - Map toJson() => { - "height": height, - "width": width, - "maximized": maximized, - }; -} - -class WindowManagerTools with WidgetsBindingObserver { - static WindowManagerTools? _instance; - static WindowManagerTools get instance => _instance!; - - WindowManagerTools._(); - - static Future initialize() async { - await windowManager.ensureInitialized(); - _instance = WindowManagerTools._(); - WidgetsBinding.instance.addObserver(instance); - - await windowManager.waitUntilReadyToShow( - const WindowOptions( - title: "Spotube", - backgroundColor: Colors.transparent, - minimumSize: Size(300, 700), - titleBarStyle: TitleBarStyle.hidden, - center: true, - ), - () async { - final savedSize = KVStoreService.windowSize; - await windowManager.setResizable(true); - if (savedSize?.maximized == true && - !(await windowManager.isMaximized())) { - await windowManager.maximize(); - } else if (savedSize != null) { - await windowManager.setSize(Size(savedSize.width, savedSize.height)); - } - - await windowManager.focus(); - await windowManager.show(); - }, - ); - } - - Size? _prevSize; - - @override - void didChangeMetrics() async { - super.didChangeMetrics(); - if (kIsMobile) return; - final size = await windowManager.getSize(); - final windowSameDimension = - _prevSize?.width == size.width && _prevSize?.height == size.height; - - if (windowSameDimension || _prevSize == null) { - _prevSize = size; - return; - } - final isMaximized = await windowManager.isMaximized(); - await KVStoreService.setWindowSize( - WindowSize( - height: size.height, - width: size.width, - maximized: isMaximized, - ), - ); - _prevSize = size; - } -} +// Conditional exports for window manager tools +export 'wm_tools_native.dart' + if (dart.library.html) 'wm_tools_web.dart'; \ No newline at end of file diff --git a/lib/services/wm_tools/wm_tools_native.dart b/lib/services/wm_tools/wm_tools_native.dart new file mode 100644 index 00000000..f60b4ac9 --- /dev/null +++ b/lib/services/wm_tools/wm_tools_native.dart @@ -0,0 +1,89 @@ +import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:spotube/services/kv_store/kv_store.dart'; +import 'package:spotube/utils/platform.dart'; +import 'package:window_manager/window_manager.dart'; + +class WindowSize { + final double height; + final double width; + final bool maximized; + + WindowSize({ + required this.height, + required this.width, + required this.maximized, + }); + + factory WindowSize.fromJson(Map json) => WindowSize( + height: json["height"], + width: json["width"], + maximized: json["maximized"], + ); + + Map toJson() => { + "height": height, + "width": width, + "maximized": maximized, + }; +} + +class WindowManagerTools with WidgetsBindingObserver { + static WindowManagerTools? _instance; + static WindowManagerTools get instance => _instance!; + + WindowManagerTools._(); + + static Future initialize() async { + await windowManager.ensureInitialized(); + _instance = WindowManagerTools._(); + WidgetsBinding.instance.addObserver(instance); + + await windowManager.waitUntilReadyToShow( + const WindowOptions( + title: "Spotube", + backgroundColor: Colors.transparent, + minimumSize: Size(300, 700), + titleBarStyle: TitleBarStyle.hidden, + center: true, + ), + () async { + final savedSize = KVStoreService.windowSize; + await windowManager.setResizable(true); + if (savedSize?.maximized == true && + !(await windowManager.isMaximized())) { + await windowManager.maximize(); + } else if (savedSize != null) { + await windowManager.setSize(Size(savedSize.width, savedSize.height)); + } + + await windowManager.focus(); + await windowManager.show(); + }, + ); + } + + Size? _prevSize; + + @override + void didChangeMetrics() async { + super.didChangeMetrics(); + if (kIsMobile) return; + final size = await windowManager.getSize(); + final windowSameDimension = + _prevSize?.width == size.width && _prevSize?.height == size.height; + + if (windowSameDimension || _prevSize == null) { + _prevSize = size; + return; + } + final isMaximized = await windowManager.isMaximized(); + await KVStoreService.setWindowSize( + WindowSize( + height: size.height, + width: size.width, + maximized: isMaximized, + ), + ); + _prevSize = size; + } +} diff --git a/lib/services/wm_tools/wm_tools_web.dart b/lib/services/wm_tools/wm_tools_web.dart new file mode 100644 index 00000000..e2bf899e --- /dev/null +++ b/lib/services/wm_tools/wm_tools_web.dart @@ -0,0 +1,46 @@ +import 'package:flutter/widgets.dart'; + +class WindowSize { + final double height; + final double width; + final bool maximized; + + WindowSize({ + required this.height, + required this.width, + required this.maximized, + }); + + factory WindowSize.fromJson(Map json) => WindowSize( + height: json["height"], + width: json["width"], + maximized: json["maximized"], + ); + + Map toJson() => { + "height": height, + "width": width, + "maximized": maximized, + }; +} + +class WindowManagerTools with WidgetsBindingObserver { + static WindowManagerTools? _instance; + static WindowManagerTools get instance => _instance!; + + WindowManagerTools._(); + + static Future initialize() async { + // Web doesn't need window manager initialization + _instance = WindowManagerTools._(); + WidgetsBinding.instance.addObserver(instance); + } + + Size? _prevSize; + + @override + void didChangeMetrics() async { + super.didChangeMetrics(); + // Web implementation - no window size saving needed + } +} \ No newline at end of file