Skip to content

Commit

Permalink
feat: Android 扩展导入
Browse files Browse the repository at this point in the history
  • Loading branch information
MiaoMint committed Jul 6, 2023
1 parent 4ab1331 commit 85cb14e
Show file tree
Hide file tree
Showing 5 changed files with 282 additions and 78 deletions.
182 changes: 118 additions & 64 deletions lib/pages/extension/view.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import 'dart:io';

import 'package:fluent_ui/fluent_ui.dart' as fluent;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:miru_app/main.dart';
import 'package:miru_app/pages/extension/controller.dart';
import 'package:miru_app/pages/extension/widgets/extension_tile.dart';
import 'package:miru_app/pages/extension_repo/view.dart';
import 'package:miru_app/utils/extension.dart';
import 'package:miru_app/utils/router.dart';
import 'package:miru_app/widgets/button.dart';
import 'package:miru_app/widgets/messenger.dart';
import 'package:miru_app/widgets/platform_widget.dart';
import 'package:url_launcher/url_launcher.dart';

Expand All @@ -28,90 +34,121 @@ class _ExtensionPageState extends State<ExtensionPage> {
// 导入扩展对话框
_importDialog() {
String url = '';
fluent.showDialog(
showPlatformDialog(
context: context,
builder: (context) => fluent.ContentDialog(
title: const Text("导入扩展"),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
fluent.TextBox(
placeholder: "扩展地址",
title: "导入扩展",
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
PlatformWidget(
androidWidget: TextField(
decoration: const InputDecoration(
labelText: "扩展地址",
hintText: "https://example.com/extension.js",
),
onChanged: (value) {
url = value;
},
),
const SizedBox(height: 16),
const Row(
children: [
Icon(fluent.FluentIcons.error),
SizedBox(width: 8),
Text(
"你可以通过链接导入扩展,\n或者点击下方的扩展目录,将扩展文件\n放入其中。",
softWrap: true,
)
],
desktopWidget: fluent.TextBox(
placeholder: "扩展地址",
onChanged: (value) {
url = value;
},
),
],
),
actions: [
fluent.Button(
onPressed: () {
router.pop();
},
child: const Text("取消"),
),
fluent.FilledButton(
onPressed: () async {
router.pop();
// 定位目录
final dir = await ExtensionUtils.getExtensionsDir;
final uri = Uri.directory(dir);
await launchUrl(uri);
},
child: const Text("扩展目录"),
),
fluent.FilledButton(
onPressed: () async {
Navigator.of(context).pop();
await ExtensionUtils.install(url, context);
},
child: const Text("通过链接导入"),
const SizedBox(height: 16),
const Row(
children: [
Icon(fluent.FluentIcons.error),
SizedBox(width: 8),
Text(
"你可以通过链接导入扩展,\n或者点击下方的扩展目录,将扩展文件\n放入其中。",
softWrap: true,
)
],
),
],
),
actions: [
PlatformButton(
onPressed: () {
RouterUtils.pop();
},
child: const Text("取消"),
),
PlatformFilledButton(
onPressed: () async {
RouterUtils.pop();
// 定位目录
final dir = await ExtensionUtils.getExtensionsDir;
if (Platform.isAndroid) {
// 复制 dir
Clipboard.setData(ClipboardData(text: dir));
// ignore: use_build_context_synchronously
showPlatformSnackbar(
context: context,
title: '扩展目录',
content: '已复制到剪贴板',
);
return;
}
final uri = Uri.directory(dir);
await launchUrl(uri);
},
child: const Text("扩展目录"),
),
PlatformFilledButton(
onPressed: () async {
RouterUtils.pop();
await ExtensionUtils.install(url, context);
},
child: const Text("通过链接导入"),
),
],
);
}

// 加载错误对话框
_loadErrorDialog() {
fluent.showDialog(
showPlatformDialog(
context: context,
builder: (context) => fluent.ContentDialog(
title: const Text("错误信息"),
content: ListView(
shrinkWrap: true,
title: "错误信息",
content: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// 输出key 和 value
for (final e in c.errors.entries)
fluent.Card(
margin: const EdgeInsets.only(bottom: 8),
child: Text(
"${e.key}: ${e.value}",
PlatformWidget(
androidWidget: Card(
margin: const EdgeInsets.only(bottom: 8),
child: Container(
padding: const EdgeInsets.all(16),
child: Text(
"${e.key}: ${e.value}",
),
),
),
desktopWidget: fluent.Card(
margin: const EdgeInsets.only(bottom: 8),
child: Text(
"${e.key}: ${e.value}",
),
),
),
],
),
actions: [
fluent.Button(
onPressed: () {
router.pop();
},
child: const Text("确定"),
),
],
),
actions: [
PlatformButton(
onPressed: () {
RouterUtils.pop();
},
child: const Text("确定"),
),
],
);
}

Expand All @@ -122,10 +159,27 @@ class _ExtensionPageState extends State<ExtensionPage> {
child: Scaffold(
appBar: AppBar(
title: const Text("扩展"),
bottom: const TabBar(tabs: [
Tab(text: "已安装"),
Tab(text: "仓库"),
]),
bottom: const TabBar(
tabs: [
Tab(text: "已安装"),
Tab(text: "仓库"),
],
),
actions: [
if (c.errors.isNotEmpty)
IconButton(
icon: const Icon(Icons.error),
onPressed: () {
_loadErrorDialog();
},
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_importDialog();
},
child: const Icon(Icons.add),
),
body: TabBarView(children: [
ListView(
Expand Down
28 changes: 14 additions & 14 deletions lib/utils/extension.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import 'package:desktop_multi_window/desktop_multi_window.dart';
import 'package:dio/dio.dart';
import 'package:fluent_ui/fluent_ui.dart';
import 'package:get/get.dart';
import 'package:miru_app/main.dart';
import 'package:miru_app/models/extension.dart';
import 'package:miru_app/pages/extension/controller.dart';
import 'package:miru_app/pages/search/controller.dart';
import 'package:miru_app/pages/settings/controller.dart';
import 'package:miru_app/utils/extension_runtime.dart';
import 'package:miru_app/utils/miru_directory.dart';
import 'package:miru_app/utils/router.dart';
import 'package:miru_app/widgets/button.dart';
import 'package:miru_app/widgets/messenger.dart';
import 'package:path/path.dart' as path;

class ExtensionUtils {
Expand Down Expand Up @@ -86,20 +88,18 @@ class ExtensionUtils {
// 保存文件
File(savePath).writeAsStringSync(res.data!);
} catch (e) {
showDialog(
showPlatformDialog(
context: context,
builder: (context) => ContentDialog(
title: const Text("安装错误"),
content: Text(e.toString()),
actions: [
Button(
child: const Text("关闭"),
onPressed: () {
router.pop();
},
)
],
),
title: "安装错误",
content: Text(e.toString()),
actions: [
PlatformButton(
child: const Text("关闭"),
onPressed: () {
RouterUtils.pop();
},
)
],
);
rethrow;
}
Expand Down
13 changes: 13 additions & 0 deletions lib/utils/router.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import 'dart:io';

import 'package:get/get.dart';
import 'package:miru_app/main.dart';

class RouterUtils {
static pop() {
if (Platform.isAndroid) {
return Get.back();
}
return router.pop();
}
}
81 changes: 81 additions & 0 deletions lib/widgets/button.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import 'package:fluent_ui/fluent_ui.dart' as fluent;
import 'package:flutter/material.dart';
import 'package:miru_app/widgets/platform_widget.dart';

class PlatformButton extends StatelessWidget {
const PlatformButton({
Key? key,
required this.child,
this.onPressed,
}) : super(key: key);
final Widget child;
final VoidCallback? onPressed;

Widget _builaAndroidButton(BuildContext context) {
return ElevatedButton(onPressed: onPressed, child: child);
}

Widget _builaDesktopButton(BuildContext context) {
return fluent.Button(onPressed: onPressed, child: child);
}

@override
Widget build(BuildContext context) {
return PlatformBuildWidget(
androidBuilder: _builaAndroidButton,
desktopBuilder: _builaDesktopButton,
);
}
}

class PlatformFilledButton extends StatelessWidget {
const PlatformFilledButton({
Key? key,
required this.child,
this.onPressed,
}) : super(key: key);
final Widget child;
final VoidCallback? onPressed;

Widget _builaAndroidButton(BuildContext context) {
return FilledButton(onPressed: onPressed, child: child);
}

Widget _builaDesktopButton(BuildContext context) {
return fluent.FilledButton(onPressed: onPressed, child: child);
}

@override
Widget build(BuildContext context) {
return PlatformBuildWidget(
androidBuilder: _builaAndroidButton,
desktopBuilder: _builaDesktopButton,
);
}
}

class PlatformTextButton extends StatelessWidget {
const PlatformTextButton({
Key? key,
required this.child,
this.onPressed,
}) : super(key: key);
final Widget child;
final VoidCallback? onPressed;

Widget _builaAndroidButton(BuildContext context) {
return TextButton(onPressed: onPressed, child: child);
}

Widget _builaDesktopButton(BuildContext context) {
return fluent.HyperlinkButton(onPressed: onPressed, child: child);
}

@override
Widget build(BuildContext context) {
return PlatformBuildWidget(
androidBuilder: _builaAndroidButton,
desktopBuilder: _builaDesktopButton,
);
}
}
Loading

0 comments on commit 85cb14e

Please sign in to comment.