Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support launch at startup #532

Merged
merged 2 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion ui/flutter/lib/app/modules/app/controllers/app_controller.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:ui';

import 'package:app_links/app_links.dart';
import 'package:flutter/material.dart';
import 'package:flutter_foreground_task/flutter_foreground_task.dart';
import 'package:get/get.dart';
import 'package:gopeed/database/entity.dart';
import 'package:launch_at_startup/launch_at_startup.dart';
import 'package:lecle_downloads_path_provider/lecle_downloads_path_provider.dart';
import 'package:path_provider/path_provider.dart';
import 'package:tray_manager/tray_manager.dart';
Expand All @@ -18,7 +19,9 @@ import '../../../../api/api.dart';
import '../../../../api/model/downloader_config.dart';
import '../../../../core/common/start_config.dart';
import '../../../../database/database.dart';
import '../../../../database/entity.dart';
import '../../../../i18n/message.dart';
import '../../../../main.dart';
import '../../../../util/locale_manager.dart';
import '../../../../util/log_util.dart';
import '../../../../util/package_info.dart';
Expand Down Expand Up @@ -73,6 +76,7 @@ final allTrackerSubscribeUrlCdns = Map.fromIterable(allTrackerSubscribeUrls,
class AppController extends GetxController with WindowListener, TrayListener {
static StartConfig? _defaultStartConfig;

final autoStartup = false.obs;
final startConfig = StartConfig().obs;
final runningPort = 0.obs;
final downloaderConfig = DownloaderConfig().obs;
Expand All @@ -98,6 +102,9 @@ class AppController extends GetxController with WindowListener, TrayListener {

_initTrackerUpdate().onError((error, stackTrace) =>
logger.w("initTrackerUpdate error", error, stackTrace));

_initLaunchAtStartup().onError((error, stackTrace) =>
logger.w("initLaunchAtStartup error", error, stackTrace));
}

@override
Expand All @@ -114,6 +121,12 @@ class AppController extends GetxController with WindowListener, TrayListener {
}
}

// According to the system_manager document, make sure to call setState once on the onWindowFocus event.
@override
void onWindowFocus() {
refresh();
}

@override
void onTrayIconMouseDown() {
windowManager.show();
Expand Down Expand Up @@ -431,6 +444,17 @@ class AppController extends GetxController with WindowListener, TrayListener {
}
}

Future<void> _initLaunchAtStartup() async {
if (!Util.isWindows() && !Util.isLinux()) {
return;
}
launchAtStartup.setup(
appName: packageInfo.appName,
appPath: Platform.resolvedExecutable,
args: ['--${Args.flagHidden}']);
autoStartup.value = await launchAtStartup.isEnabled();
}

Future<void> saveConfig() async {
Database.instance.saveStartConfig(StartConfigEntity(
network: startConfig.value.network,
Expand Down
35 changes: 32 additions & 3 deletions ui/flutter/lib/app/modules/setting/views/setting_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:launch_at_startup/launch_at_startup.dart';
import 'package:url_launcher/url_launcher.dart';

import '../../../../api/model/downloader_config.dart';
import '../../../../database/database.dart';
import '../../../../i18n/message.dart';
import '../../../../util/input_formatter.dart';
import '../../../../util/locale_manager.dart';
import '../../../../util/log_util.dart';
import '../../../../util/message.dart';
import '../../../../util/package_info.dart';
import '../../../../util/util.dart';
Expand Down Expand Up @@ -130,9 +131,36 @@ class SettingView extends GetView<SettingController> {
"https://addons.mozilla.org/zh-CN/firefox/addon/gopeed-extension",
),
],
).paddingOnly(top: 5, bottom: 5));
).paddingOnly(top: 5));
}

// Currently auto startup only support Windows and Linux
final buildAutoStartup = !Util.isWindows() && !Util.isLinux()
? () => null
: _buildConfigItem('launchAtStartup'.tr, () {
return appController.autoStartup.value ? 'on'.tr : 'off'.tr;
}, (Key key) {
return Container(
alignment: Alignment.centerLeft,
child: Switch(
value: appController.autoStartup.value,
onChanged: (bool value) async {
try {
if (value) {
await launchAtStartup.enable();
} else {
await launchAtStartup.disable();
}
appController.autoStartup.value = value;
} catch (e) {
showErrorMessage(e);
logger.e('launchAtStartup fail', e);
}
},
),
);
});

// http config items start
final httpConfig = downloaderCfg.value.protocolConfig.http;
final buildHttpUa =
Expand Down Expand Up @@ -784,7 +812,8 @@ class SettingView extends GetView<SettingController> {
children: _addDivider([
buildDownloadDir(),
buildMaxRunning(),
buildBrowserExtension()
buildBrowserExtension(),
buildAutoStartup(),
]),
)),
const Text('HTTP'),
Expand Down
1 change: 1 addition & 0 deletions ui/flutter/lib/i18n/langs/en_us.dart
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,6 @@ const enUS = {
'thanksDesc':
'Thanks to all the contributors who have helped build and develop the Gopeed community!',
'browserExtension': 'Browser Extension',
'launchAtStartup': 'Launch at Startup',
},
};
1 change: 1 addition & 0 deletions ui/flutter/lib/i18n/langs/zh_cn.dart
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,6 @@ const zhCN = {
'thanks': '鸣谢',
'thanksDesc': '感谢所有为 Gopeed 社区建设添砖加瓦的贡献者们!',
'browserExtension': '浏览器扩展',
'launchAtStartup': '开机自动运行',
}
};
1 change: 1 addition & 0 deletions ui/flutter/lib/i18n/langs/zh_tw.dart
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,6 @@ const zhTW = {
'thanks': '感謝',
'thanksDesc': '感謝所有為 Gopeed 社區建設添磚加瓦的貢獻者們!',
'browserExtension': '瀏覽器擴充程式',
'launchAtStartup': '開機自動運行',
}
};
39 changes: 28 additions & 11 deletions ui/flutter/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:args/args.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_foreground_task/flutter_foreground_task.dart';
Expand All @@ -17,14 +18,28 @@ import 'util/mac_secure_util.dart';
import 'util/package_info.dart';
import 'util/util.dart';

void main() async {
await init();
class Args {
static const flagHidden = "hidden";

bool hidden = false;

Args.parse(List<String> args) {
final parser = ArgParser();
parser.addFlag(flagHidden);
final results = parser.parse(args);
hidden = results.flag(flagHidden);
}
}

void main(List<String> arguments) async {
final args = Args.parse(arguments);
await init(args);
onStart();

runApp(const AppView());
}

Future<void> init() async {
Future<void> init(Args args) async {
WidgetsFlutterBinding.ensureInitialized();
await Util.initStorageDir();
await Database.instance.init();
Expand All @@ -37,8 +52,10 @@ Future<void> init() async {
skipTaskbar: false,
);
await windowManager.waitUntilReadyToShow(windowOptions, () async {
await windowManager.show();
await windowManager.focus();
if (!args.hidden) {
await windowManager.show();
await windowManager.focus();
}
await windowManager.setPreventClose(true);
// windows_manager has a bug where when window to be maximized, it will be unmaximized immediately, so can't implement this feature currently.
// https://github.com/leanflutter/window_manager/issues/412
Expand All @@ -50,6 +67,12 @@ Future<void> init() async {

initLogger();

try {
await initPackageInfo();
} catch (e) {
logger.e("init package info fail", e);
}

final controller = Get.put(AppController());
try {
await controller.loadStartConfig();
Expand Down Expand Up @@ -81,12 +104,6 @@ Future<void> init() async {
} catch (e) {
logger.e("load config fail", e);
}

try {
await initPackageInfo();
} catch (e) {
logger.e("init package info fail", e);
}
}

Future<void> onStart() async {
Expand Down
2 changes: 1 addition & 1 deletion ui/flutter/lib/util/util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class Util {
static Future<void> initStorageDir() async {
var storageDir = "";
if (Util.isWindows()) {
storageDir = "./";
storageDir = File(Platform.resolvedExecutable).parent.path;
} else if (!Util.isWeb()) {
if (Util.isLinux()) {
storageDir = File(Platform.resolvedExecutable).parent.path;
Expand Down
3 changes: 2 additions & 1 deletion ui/flutter/linux/my_application.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ static void my_application_activate(GApplication* application) {
}

gtk_window_set_default_size(window, 1280, 720);
gtk_widget_show(GTK_WIDGET(window));
//gtk_widget_show(GTK_WIDGET(window));
gtk_widget_realize(GTK_WIDGET(window));

g_autoptr(FlDartProject) project = fl_dart_project_new();
fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments);
Expand Down
6 changes: 6 additions & 0 deletions ui/flutter/macos/Runner/MainFlutterWindow.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Cocoa
import FlutterMacOS
import window_manager

class MainFlutterWindow: NSWindow {
override func awakeFromNib() {
Expand All @@ -12,4 +13,9 @@ class MainFlutterWindow: NSWindow {

super.awakeFromNib()
}

override public func order(_ place: NSWindow.OrderingMode, relativeTo otherWin: Int) {
super.order(place, relativeTo: otherWin)
hiddenWindowAtLaunch()
}
}
22 changes: 19 additions & 3 deletions ui/flutter/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ packages:
source: hosted
version: "3.4.10"
args:
dependency: transitive
dependency: "direct main"
description:
name: args
sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a"
url: "https://pub.dev"
source: hosted
version: "2.4.2"
version: "2.5.0"
async:
dependency: transitive
description:
Expand Down Expand Up @@ -493,6 +493,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "6.7.1"
launch_at_startup:
dependency: "direct main"
description:
name: launch_at_startup
sha256: "93fc5638e088290004fae358bae691486673d469957d461d9dae5b12248593eb"
url: "https://pub.dev"
source: hosted
version: "0.2.2"
lecle_downloads_path_provider:
dependency: "direct main"
description:
Expand Down Expand Up @@ -1130,6 +1138,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.1.4"
win32_registry:
dependency: transitive
description:
name: win32_registry
sha256: "1c52f994bdccb77103a6231ad4ea331a244dbcef5d1f37d8462f713143b0bfae"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
window_manager:
dependency: "direct main"
description:
Expand Down
2 changes: 2 additions & 0 deletions ui/flutter/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ dependencies:
tray_manager: ^0.2.1
lecle_downloads_path_provider: ^0.0.2+8
hive: ^2.2.3
launch_at_startup: ^0.2.2
args: ^2.5.0
dev_dependencies:
flutter_test:
sdk: flutter
Expand Down
1 change: 0 additions & 1 deletion ui/flutter/windows/runner/flutter_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ bool FlutterWindow::OnCreate() {
SetChildContent(flutter_controller_->view()->GetNativeWindow());

flutter_controller_->engine()->SetNextFrameCallback([&]() {
this->Show();
});

// Flutter can complete the first frame before the "show window" callback is
Expand Down
Loading