diff --git a/build-windows-beta.ps1 b/build-windows-beta.ps1 new file mode 100644 index 00000000..0b59d0d1 --- /dev/null +++ b/build-windows-beta.ps1 @@ -0,0 +1,29 @@ +param( + [string[]]$FlutterArgs = @() +) + +# Set the build flag for this process only +$env:MOONFIN_BETA_BUILD = "true" + +# wipe out the windows build directory if you're running into build problems +#$buildDir = Join-Path $PSScriptRoot "build\windows\x64" +#if (Test-Path $buildDir) { +# Write-Host "Removing existing Windows build dir: $buildDir" +# Remove-Item -Recurse -Force $buildDir +#} + +# Ensure the dart-define is passed to the Flutter tool so `const.fromEnvironment` +# in Dart will be set at compile time. Also allow additional args to be passed. +$argsList = @("build", "windows", "--release") + $FlutterArgs +if (-not ($argsList -contains "--dart-define=MOONFIN_BETA_BUILD=true")) { + $argsList += "--dart-define=MOONFIN_BETA_BUILD=true" +} +Write-Host "Running: flutter $($argsList -join ' ')" +& flutter @argsList +$exit = $LASTEXITCODE +if ($exit -ne 0) { + Write-Error "flutter build windows failed with exit code $exit" + exit $exit +} + +Write-Host "Built Windows Beta version" diff --git a/lib/data/database/database_connection_impl_io.dart b/lib/data/database/database_connection_impl_io.dart index 6fe00639..504d55fa 100644 --- a/lib/data/database/database_connection_impl_io.dart +++ b/lib/data/database/database_connection_impl_io.dart @@ -2,12 +2,13 @@ import 'dart:io'; import 'package:drift/drift.dart'; import 'package:drift/native.dart'; +import 'package:moonfin/data/services/storage_path_service.dart'; import 'package:path_provider/path_provider.dart'; QueryExecutor openConnection() { return LazyDatabase(() async { final docs = await getApplicationDocumentsDirectory(); - final dbDir = Directory('${docs.path}/Moonfin/DB'); + final dbDir = Directory('${docs.path}/${StoragePathService.appFolderName}/DB'); if (!dbDir.existsSync()) { await dbDir.create(recursive: true); } diff --git a/lib/data/services/storage_path_service.dart b/lib/data/services/storage_path_service.dart index aa532ec4..72c7b7cb 100644 --- a/lib/data/services/storage_path_service.dart +++ b/lib/data/services/storage_path_service.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'dart:math'; +import 'package:flutter/foundation.dart'; import 'package:get_it/get_it.dart'; import 'package:path_provider/path_provider.dart'; @@ -17,6 +18,21 @@ class StoragePathService { void clearCache() => _cachedRoot = null; + static String get appFolderName { + // get the flavor passed via --flavor + // android/androidtv/macos/ios/linux too? - only android/androidtv are set up currently + const flavor = String.fromEnvironment('FLUTTER_APP_FLAVOR'); + final betaFlavor = flavor.toLowerCase().contains('beta'); + + // check for --dart-define MOONFIN_BETA_BUILD=true from CLI + // needed for windows, and maybe linux if we don't do a flavor + const betaDartDefine = bool.fromEnvironment('MOONFIN_BETA_BUILD'); + + final isBeta = betaFlavor || betaDartDefine; + debugPrint('StoragePathService: isBeta=$isBeta (flavor=$flavor, betaDartDefine=$betaDartDefine)'); + return isBeta ? 'Moonfin Beta' : 'Moonfin'; + } + Future getOfflineRoot() async { if (_cachedRoot != null) return _cachedRoot!; @@ -45,10 +61,10 @@ class StoragePathService { if (PlatformDetection.isAndroid) { final extDir = await getExternalStorageDirectory(); final base = extDir ?? await getApplicationDocumentsDirectory(); - dir = Directory('${base.path}/Moonfin'); + dir = Directory('${base.path}/$appFolderName'); } else if (PlatformDetection.isIOS) { final docs = await getApplicationDocumentsDirectory(); - dir = Directory('${docs.path}/Moonfin'); + dir = Directory('${docs.path}/$appFolderName'); } else { final support = await getApplicationSupportDirectory(); dir = Directory('${support.path}/Downloads'); @@ -82,7 +98,7 @@ class StoragePathService { Future getDatabaseFile() async { final docs = await getApplicationDocumentsDirectory(); - final dbDir = Directory('${docs.path}/Moonfin/DB'); + final dbDir = Directory('${docs.path}/$appFolderName/DB'); if (!await dbDir.exists()) await dbDir.create(recursive: true); return File('${dbDir.path}/offline.db'); } @@ -90,7 +106,10 @@ class StoragePathService { Future getImageCacheDir() async { if (PlatformDetection.isAndroid && _useMediaStore) { final support = await getApplicationSupportDirectory(); - final dir = Directory('${support.path}/Moonfin/images'); + final dir = (!Platform.isWindows) + ? Directory('${support.path}/$appFolderName/images') + // windows includes the app folder + : Directory('${support.path}/images'); if (!await dir.exists()) await dir.create(recursive: true); return dir; } diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index d54c29d8..707a6733 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -2,8 +2,16 @@ cmake_minimum_required(VERSION 3.13) project(runner LANGUAGES CXX) -set(BINARY_NAME "moonfin") -set(APPLICATION_ID "org.moonfin.linux") +# for CLI - flutter run --dart-define=MOONFIN_BETA_BUILD=true +# for launch configurations - add an env for "MOONFIN_BETA_BUILD": "true" +if(DEFINED ENV{MOONFIN_BETA_BUILD}) + set(BINARY_NAME "moonfin-beta") + set(APPLICATION_ID "org.moonfin.linux.beta") + add_definitions(-DMOONFIN_BETA_BUILD) +else() + set(BINARY_NAME "moonfin") + set(APPLICATION_ID "org.moonfin.linux") +endif() # Explicitly opt in to modern CMake behaviors to avoid warnings with recent # versions of CMake. diff --git a/linux/runner/my_application.cc b/linux/runner/my_application.cc index 302f7303..1c70f4ae 100644 --- a/linux/runner/my_application.cc +++ b/linux/runner/my_application.cc @@ -17,7 +17,11 @@ static void my_application_activate(GApplication* application) { GtkWindow* window = GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); +#ifdef MOONFIN_BETA_BUILD + gtk_window_set_title(window, "Moonfin Beta"); +#else gtk_window_set_title(window, "Moonfin"); +#endif gtk_window_set_default_size(window, 1280, 720); gtk_widget_show(GTK_WIDGET(window)); diff --git a/windows/CMakeLists.txt b/windows/CMakeLists.txt index f2ebb31e..f0c00fdb 100644 --- a/windows/CMakeLists.txt +++ b/windows/CMakeLists.txt @@ -2,7 +2,14 @@ cmake_minimum_required(VERSION 3.14) project(moonfin LANGUAGES CXX) -set(BINARY_NAME "moonfin") +# for CLI - flutter run --dart-define=MOONFIN_BETA_BUILD=true +# for launch configurations - add an env for "MOONFIN_BETA_BUILD": "true" +if(DEFINED ENV{MOONFIN_BETA_BUILD}) + set(BINARY_NAME "Moonfin-Beta") + add_definitions(-DMOONFIN_BETA_BUILD) +else() + set(BINARY_NAME "moonfin") +endif () # Explicitly opt in to modern CMake behaviors to avoid warnings with recent # versions of CMake. diff --git a/windows/runner/Runner.rc b/windows/runner/Runner.rc index baa35c31..0490ea76 100644 --- a/windows/runner/Runner.rc +++ b/windows/runner/Runner.rc @@ -90,12 +90,19 @@ BEGIN BLOCK "040904e4" BEGIN VALUE "CompanyName", "org.moonfin" "\0" +#ifdef MOONFIN_BETA_BUILD + VALUE "FileDescription", "Moonfin Beta" "\0" + VALUE "InternalName", "moonfin-beta" "\0" + VALUE "OriginalFilename", "moonfin-beta.exe" "\0" + VALUE "ProductName", "Moonfin Beta" "\0" +#else VALUE "FileDescription", "Moonfin" "\0" - VALUE "FileVersion", VERSION_AS_STRING "\0" VALUE "InternalName", "moonfin" "\0" - VALUE "LegalCopyright", "Copyright (C) 2026 org.moonfin. All rights reserved." "\0" VALUE "OriginalFilename", "moonfin.exe" "\0" VALUE "ProductName", "Moonfin" "\0" +#endif + VALUE "FileVersion", VERSION_AS_STRING "\0" + VALUE "LegalCopyright", "Copyright (C) 2026 org.moonfin. All rights reserved." "\0" VALUE "ProductVersion", VERSION_AS_STRING "\0" END END diff --git a/windows/runner/main.cpp b/windows/runner/main.cpp index fcbd5ef9..81ea4c63 100644 --- a/windows/runner/main.cpp +++ b/windows/runner/main.cpp @@ -27,7 +27,11 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, FlutterWindow window(project); Win32Window::Point origin(10, 10); Win32Window::Size size(1280, 720); +#ifdef MOONFIN_BETA_BUILD + if (!window.Create(L"Moonfin Beta", origin, size)) { +#else if (!window.Create(L"Moonfin", origin, size)) { +#endif return EXIT_FAILURE; } window.SetQuitOnClose(true);