Fix uri launch
This commit is contained in:
@@ -6,10 +6,9 @@ import 'package:hiddify/domain/failures.dart';
|
|||||||
import 'package:hiddify/features/common/new_version_dialog.dart';
|
import 'package:hiddify/features/common/new_version_dialog.dart';
|
||||||
import 'package:hiddify/features/common/runtime_details.dart';
|
import 'package:hiddify/features/common/runtime_details.dart';
|
||||||
import 'package:hiddify/gen/assets.gen.dart';
|
import 'package:hiddify/gen/assets.gen.dart';
|
||||||
import 'package:hiddify/utils/alerts.dart';
|
import 'package:hiddify/utils/utils.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:recase/recase.dart';
|
import 'package:recase/recase.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
|
||||||
|
|
||||||
class AboutPage extends HookConsumerWidget {
|
class AboutPage extends HookConsumerWidget {
|
||||||
const AboutPage({super.key});
|
const AboutPage({super.key});
|
||||||
@@ -76,7 +75,7 @@ class AboutPage extends HookConsumerWidget {
|
|||||||
"${t.about.version} ${value.version} ${value.buildNumber}",
|
"${t.about.version} ${value.version} ${value.buildNumber}",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -91,9 +90,8 @@ class AboutPage extends HookConsumerWidget {
|
|||||||
title: Text(t.about.sourceCode.sentenceCase),
|
title: Text(t.about.sourceCode.sentenceCase),
|
||||||
trailing: const Icon(Icons.open_in_new),
|
trailing: const Icon(Icons.open_in_new),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await launchUrl(
|
await UriUtils.tryLaunch(
|
||||||
Uri.parse(Constants.githubUrl),
|
Uri.parse(Constants.githubUrl),
|
||||||
mode: LaunchMode.externalApplication,
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -101,9 +99,8 @@ class AboutPage extends HookConsumerWidget {
|
|||||||
title: Text(t.about.telegramChannel.sentenceCase),
|
title: Text(t.about.telegramChannel.sentenceCase),
|
||||||
trailing: const Icon(Icons.open_in_new),
|
trailing: const Icon(Icons.open_in_new),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await launchUrl(
|
await UriUtils.tryLaunch(
|
||||||
Uri.parse(Constants.telegramChannelUrl),
|
Uri.parse(Constants.telegramChannelUrl),
|
||||||
mode: LaunchMode.externalApplication,
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -127,7 +124,7 @@ class AboutPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
_ => [],
|
_ => [],
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import 'package:go_router/go_router.dart';
|
|||||||
import 'package:hiddify/core/core_providers.dart';
|
import 'package:hiddify/core/core_providers.dart';
|
||||||
import 'package:hiddify/domain/app/app.dart';
|
import 'package:hiddify/domain/app/app.dart';
|
||||||
import 'package:hiddify/domain/constants.dart';
|
import 'package:hiddify/domain/constants.dart';
|
||||||
|
import 'package:hiddify/utils/utils.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:recase/recase.dart';
|
import 'package:recase/recase.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
|
||||||
|
|
||||||
// TODO add release notes
|
// TODO add release notes
|
||||||
class NewVersionDialog extends HookConsumerWidget {
|
class NewVersionDialog extends HookConsumerWidget {
|
||||||
@@ -86,9 +86,8 @@ class NewVersionDialog extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await launchUrl(
|
await UriUtils.tryLaunch(
|
||||||
Uri.parse(Constants.githubLatestReleaseUrl),
|
Uri.parse(Constants.githubLatestReleaseUrl),
|
||||||
mode: LaunchMode.externalApplication,
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: Text(t.appUpdate.updateNowBtnTxt.titleCase),
|
child: Text(t.appUpdate.updateNowBtnTxt.titleCase),
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:dartx/dartx.dart';
|
import 'package:dartx/dartx.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
@@ -14,9 +12,7 @@ import 'package:hiddify/services/service_providers.dart';
|
|||||||
import 'package:hiddify/utils/utils.dart';
|
import 'package:hiddify/utils/utils.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:recase/recase.dart';
|
import 'package:recase/recase.dart';
|
||||||
import 'package:share_plus/share_plus.dart';
|
|
||||||
import 'package:tint/tint.dart';
|
import 'package:tint/tint.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
|
||||||
|
|
||||||
class LogsPage extends HookConsumerWidget with PresLogger {
|
class LogsPage extends HookConsumerWidget with PresLogger {
|
||||||
const LogsPage({super.key});
|
const LogsPage({super.key});
|
||||||
@@ -35,18 +31,18 @@ class LogsPage extends HookConsumerWidget with PresLogger {
|
|||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
child: Text(t.logs.shareCoreLogs.sentenceCase),
|
child: Text(t.logs.shareCoreLogs.sentenceCase),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await shareFileOrOpenDir(
|
await UriUtils.tryShareOrLaunchFile(
|
||||||
filesEditor.coreLogsPath,
|
Uri.parse(filesEditor.coreLogsPath),
|
||||||
filesEditor.logsDir.uri,
|
fileOrDir: filesEditor.logsDir.uri,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
child: Text(t.logs.shareAppLogs.sentenceCase),
|
child: Text(t.logs.shareAppLogs.sentenceCase),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await shareFileOrOpenDir(
|
await UriUtils.tryShareOrLaunchFile(
|
||||||
filesEditor.appLogsPath,
|
Uri.parse(filesEditor.appLogsPath),
|
||||||
filesEditor.logsDir.uri,
|
fileOrDir: filesEditor.logsDir.uri,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -164,17 +160,4 @@ class LogsPage extends HookConsumerWidget with PresLogger {
|
|||||||
return const Scaffold();
|
return const Scaffold();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> shareFileOrOpenDir(String path, Uri dir) async {
|
|
||||||
try {
|
|
||||||
if (Platform.isWindows || Platform.isLinux) {
|
|
||||||
await launchUrl(dir);
|
|
||||||
} else {
|
|
||||||
final file = XFile(path, mimeType: "text/plain");
|
|
||||||
await Share.shareXFiles([file]);
|
|
||||||
}
|
|
||||||
} catch (err, stackTrace) {
|
|
||||||
loggy.warning("error sharing log file", err, stackTrace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,10 +7,9 @@ import 'package:hiddify/core/prefs/prefs.dart';
|
|||||||
import 'package:hiddify/core/theme/theme.dart';
|
import 'package:hiddify/core/theme/theme.dart';
|
||||||
import 'package:hiddify/features/settings/widgets/theme_mode_switch_button.dart';
|
import 'package:hiddify/features/settings/widgets/theme_mode_switch_button.dart';
|
||||||
import 'package:hiddify/services/service_providers.dart';
|
import 'package:hiddify/services/service_providers.dart';
|
||||||
import 'package:hiddify/utils/platform_utils.dart';
|
import 'package:hiddify/utils/utils.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:recase/recase.dart';
|
import 'package:recase/recase.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
|
||||||
|
|
||||||
class AppearanceSettingTiles extends HookConsumerWidget {
|
class AppearanceSettingTiles extends HookConsumerWidget {
|
||||||
const AppearanceSettingTiles({super.key});
|
const AppearanceSettingTiles({super.key});
|
||||||
@@ -111,7 +110,7 @@ class AppearanceSettingTiles extends HookConsumerWidget {
|
|||||||
trailing: const Icon(Icons.arrow_outward_outlined),
|
trailing: const Icon(Icons.arrow_outward_outlined),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final path = ref.read(filesEditorServiceProvider).workingDir.uri;
|
final path = ref.read(filesEditorServiceProvider).workingDir.uri;
|
||||||
launchUrl(path);
|
await UriUtils.tryLaunch(path);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
44
lib/utils/uri_utils.dart
Normal file
44
lib/utils/uri_utils.dart
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:hiddify/utils/custom_loggers.dart';
|
||||||
|
import 'package:loggy/loggy.dart';
|
||||||
|
import 'package:share_plus/share_plus.dart';
|
||||||
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
abstract class UriUtils {
|
||||||
|
static final loggy = Loggy<InfraLogger>("UriUtils");
|
||||||
|
|
||||||
|
static Future<bool> tryShareOrLaunchFile(Uri uri, {Uri? fileOrDir}) async {
|
||||||
|
if (Platform.isWindows || Platform.isLinux) {
|
||||||
|
return tryLaunch(fileOrDir ?? uri);
|
||||||
|
}
|
||||||
|
return tryShareFile(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<bool> tryLaunch(Uri uri) async {
|
||||||
|
try {
|
||||||
|
loggy.debug("launching [$uri]");
|
||||||
|
if (!await canLaunchUrl(uri)) {
|
||||||
|
loggy.warning("can't launch [$uri]");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return launchUrl(uri, mode: LaunchMode.externalApplication);
|
||||||
|
} catch (e, stackTrace) {
|
||||||
|
loggy.warning("error launching [$uri]", e, stackTrace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<bool> tryShareFile(Uri uri, {String? mimeType}) async {
|
||||||
|
try {
|
||||||
|
loggy.debug("sharing [$uri]");
|
||||||
|
final file = XFile(uri.path, mimeType: mimeType);
|
||||||
|
final result = await Share.shareXFiles([file]);
|
||||||
|
loggy.debug("share result: ${result.raw}");
|
||||||
|
return result.status == ShareResultStatus.success;
|
||||||
|
} catch (e, stackTrace) {
|
||||||
|
loggy.warning("error sharing file [$uri]", e, stackTrace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,4 +11,5 @@ export 'number_formatters.dart';
|
|||||||
export 'placeholders.dart';
|
export 'placeholders.dart';
|
||||||
export 'platform_utils.dart';
|
export 'platform_utils.dart';
|
||||||
export 'text_utils.dart';
|
export 'text_utils.dart';
|
||||||
|
export 'uri_utils.dart';
|
||||||
export 'validators.dart';
|
export 'validators.dart';
|
||||||
|
|||||||
Reference in New Issue
Block a user