Skip to content

Commit 434f4a3

Browse files
committed
add mirror repo support, fix s3
1 parent d26d7b2 commit 434f4a3

File tree

16 files changed

+644
-57
lines changed

16 files changed

+644
-57
lines changed

README.org

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@
77

88
** 支持的存储
99
- [X] 本地文件
10-
- [X] ftp
11-
- [X] sftp
12-
- [X] smb
13-
- [X] webdav
10+
- [X] FTP
11+
- [X] SFTP
12+
- [X] S3
13+
- [X] SMB
14+
- [X] Webdav
15+
- [X] Alist
16+
- [X] Mirror(镜像站,支持文件查看和下载,支持格式:清华源、阿里源或者其他 *nginx*格式的文件列表)
1417
- [X] 又拍云
1518

1619
** 截图

app/lib/api/file/pages/repo_edit.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ class _RepoEditState extends ConsumerState<RepoEdit> {
191191
),
192192
textAlign: TextAlign.center,
193193
),
194-
)
194+
),
195195
],
196196
),
197197
],

app/lib/api/file/widgets/file_view.dart

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -138,16 +138,14 @@ class _FileViewState extends ConsumerState<FileView> {
138138
spacing: 8,
139139
children: [
140140
Text(
141-
TimeUtil.pbToString(row.updatedAt, "yyyy-MM-dd HH:mm:ss"),
141+
TimeUtil.pbToString(row.updatedAt, "yyyy-MM-dd HH:mm"),
142142
style: const TextStyle(fontSize: 12),
143143
),
144-
if (Breakpoint.isDesktop(context) && row.type != "DIR")
144+
if (row.type != "DIR")
145145
Text(
146-
"文件大小: {size}".tr(
147-
context,
148-
args: {"size": Util.formatSize(row.size)},
149-
),
150-
style: const TextStyle(fontSize: 12)),
146+
Util.formatSize(row.size),
147+
style: const TextStyle(fontSize: 12),
148+
),
151149
],
152150
),
153151
selected: selection.contains(row),

app/lib/api/file/widgets/repo/form.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import "alist.dart";
1313
import "local.dart";
1414
import "upyun.dart";
1515
import "webdav.dart";
16+
import "mirror.dart";
1617

1718
enum DriverType {
1819
s3,
@@ -23,6 +24,7 @@ enum DriverType {
2324
local,
2425
upyun,
2526
webdav,
27+
mirror,
2628
}
2729

2830
extension DriverTypeTypeExtension on DriverType {
@@ -36,6 +38,7 @@ extension DriverTypeTypeExtension on DriverType {
3638
DriverType.local: "本地",
3739
DriverType.upyun: "又拍云",
3840
DriverType.webdav: "Webdav",
41+
DriverType.mirror: "Mirror",
3942
};
4043
return labels[this] ?? "unknown";
4144
}
@@ -149,6 +152,8 @@ class DriverForm extends StatelessWidget {
149152
return Upyun(form: form);
150153
case "webdav":
151154
return Webdav(form: form);
155+
case "mirror":
156+
return Mirror(form: form);
152157
default:
153158
return const SizedBox.shrink();
154159
}

app/lib/api/file/widgets/repo/local.dart

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import 'dart:convert';
22

33
import 'package:flutter/material.dart';
4-
import 'package:file_picker/file_picker.dart';
4+
import 'package:permission_handler/permission_handler.dart';
55

6+
import 'package:maple_file/app/app.dart';
67
import 'package:maple_file/app/i18n.dart';
8+
import 'package:maple_file/common/utils/util.dart';
79
import 'package:maple_file/common/widgets/dialog.dart';
810
import 'package:maple_file/generated/proto/api/file/repo.pb.dart';
911

@@ -66,6 +68,36 @@ class _LocalState extends State<Local> {
6668
],
6769
),
6870
),
71+
if (Util.isAndroid())
72+
FutureBuilder(
73+
future: Permission.manageExternalStorage.status,
74+
builder: (context, snapshot) {
75+
if (snapshot.hasData && (snapshot.data?.isDenied ?? false)) {
76+
return Column(
77+
mainAxisSize: MainAxisSize.min,
78+
children: [
79+
const SizedBox(height: 4),
80+
Text(
81+
"本地文件的访问需要授权设备的读写权限".tr(context),
82+
style: Theme.of(context).textTheme.bodySmall,
83+
),
84+
TextButton(
85+
child: Text("去设置 >>".tr(context)),
86+
onPressed: () async {
87+
await Permission.manageExternalStorage
88+
.onDeniedCallback(() {
89+
Messenger.showSnackBar(
90+
Text("拒绝权限可能会导致本地存储无法获取到文件信息".tr(context)),
91+
);
92+
}).request();
93+
},
94+
),
95+
],
96+
);
97+
}
98+
return const SizedBox.shrink();
99+
},
100+
),
69101
SizedBox(
70102
width: double.infinity,
71103
child: ElevatedButton(
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import 'dart:convert';
2+
3+
import 'package:flutter/material.dart';
4+
5+
import 'package:maple_file/app/i18n.dart';
6+
import 'package:maple_file/common/widgets/dialog.dart';
7+
import 'package:maple_file/generated/proto/api/file/repo.pb.dart';
8+
9+
import 'form.dart';
10+
11+
class Mirror extends StatefulWidget {
12+
const Mirror({super.key, required this.form});
13+
14+
final Repo form;
15+
16+
@override
17+
State<Mirror> createState() => _MirrorState();
18+
}
19+
20+
class _MirrorState extends State<Mirror> {
21+
late Map<String, dynamic> _option;
22+
23+
@override
24+
void initState() {
25+
super.initState();
26+
27+
_option = widget.form.option == "" ? {} : jsonDecode(widget.form.option);
28+
}
29+
30+
@override
31+
Widget build(BuildContext context) {
32+
return Card(
33+
child: Column(
34+
children: [
35+
DriverFormField(
36+
label: "源站".tr(context),
37+
value: _option["endpoint"],
38+
isRequired: true,
39+
onTap: (result) {
40+
setState(() {
41+
_option["endpoint"] = result;
42+
});
43+
44+
widget.form.option = jsonEncode(_option);
45+
},
46+
),
47+
ListTile(
48+
title: Text('源站格式'.tr(context)),
49+
trailing: Wrap(
50+
crossAxisAlignment: WrapCrossAlignment.center,
51+
children: [
52+
Text(_option["format"] ?? "未选择".tr(context)),
53+
const Icon(Icons.chevron_right),
54+
],
55+
),
56+
onTap: () async {
57+
final result = await showListDialog(context, items: [
58+
ListDialogItem(value: "nginx"),
59+
ListDialogItem(value: "tuna"),
60+
ListDialogItem(value: "aliyun"),
61+
]);
62+
if (result != null) {
63+
setState(() {
64+
_option["format"] = result;
65+
});
66+
widget.form.option = jsonEncode(_option);
67+
}
68+
},
69+
),
70+
DriverFormField(
71+
label: "根目录".tr(context),
72+
value: _option["root_path"],
73+
onTap: (result) {
74+
setState(() {
75+
_option["root_path"] = result;
76+
});
77+
78+
widget.form.option = jsonEncode(_option);
79+
},
80+
),
81+
],
82+
),
83+
);
84+
}
85+
}

app/lib/api/file/widgets/repo/s3.dart

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@ class _S3State extends State<S3> {
2323
void initState() {
2424
super.initState();
2525

26-
_option = widget.form.option == ""
27-
? {"port": 22}
28-
: jsonDecode(widget.form.option);
26+
_option = widget.form.option == "" ? {} : jsonDecode(widget.form.option);
2927
}
3028

3129
@override
@@ -34,7 +32,7 @@ class _S3State extends State<S3> {
3432
child: Column(
3533
children: [
3634
DriverFormField(
37-
label: "主机/IP".tr(context),
35+
label: "接入点".tr(context),
3836
value: _option["endpoint"],
3937
isRequired: true,
4038
onTap: (result) {
@@ -85,7 +83,6 @@ class _S3State extends State<S3> {
8583
type: DriverFormFieldType.password,
8684
label: "访问密钥".tr(context),
8785
value: _option["secret_key"],
88-
isRequired: true,
8986
onTap: (result) {
9087
setState(() {
9188
_option["secret_key"] = result;

app/lib/app/i18n/en_us.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const enUS = {
3434
"加载中...": "Loading...",
3535
"加载失败": "Load Failed",
3636
"加载成功": "Load Success",
37+
"去设置 >>": "go to setting",
3738
"同时下载任务数": "",
3839
"名称": "Name",
3940
"图标": "Icon",
@@ -46,15 +47,22 @@ const enUS = {
4647
"存储名称": "Repo Name",
4748
"存储库": "Repos",
4849
"存储桶": "",
50+
"存储状态": "",
4951
"存储类型": "Repo Driver",
52+
"存储类型:{driver}": "type: {driver}",
5053
"宫格模式": "Grid",
5154
"密码": "Password",
55+
"已取消": "",
5256
"已失败": "",
5357
"已完成": "",
5458
"已选择{count}项": "",
5559
"布局": "Layout",
5660
"帮助": "Help",
61+
"当前播放列表({length})": "",
62+
"执行失败": "",
63+
"执行成功": "",
5764
"拍照上传": "",
65+
"拒绝权限可能会导致本地存储无法获取到文件信息": "",
5866
"挂载目录": "Mount Path",
5967
"按{sort}排序": "",
6068
"接入点": "Endpoint",
@@ -77,18 +85,24 @@ const enUS = {
7785
"最后更新于 %T": "",
7886
"未找到页面": "",
7987
"未知": "Knonwn",
88+
"未知状态": "",
8089
"未知的文件类型,无法查看文件,请下载到本地查看": "",
8190
"未设置": "",
8291
"未选择": "",
92+
"本地文件的访问需要授权设备的读写权限": "",
8393
"查看详情": "",
8494
"根目录": "",
95+
"正在取消": "",
96+
"正在执行": "",
8597
"正在进行": "",
8698
"正序": "ASC",
8799
"没有更多": "No More",
88100
"测试连接": "test repo",
89101
"添加存储": "Add Repo",
90102
"添加新存储": "Add Repo",
91103
"清除任务": "Clear Task",
104+
"源站": "",
105+
"源站格式": "",
92106
"用户": "username",
93107
"目录": "directory",
94108
"目录权限": "directory's permission",
@@ -102,6 +116,7 @@ const enUS = {
102116
"移动": "Move",
103117
"移动文件到": "Move file to",
104118
"端口": "Port",
119+
"等待执行": "",
105120
"简介": "",
106121
"类型": "Type",
107122
"红枫云盘": "Maple File",

app/lib/app/i18n/zh_cn.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const zhCN = {
3434
"加载中...": "",
3535
"加载失败": "",
3636
"加载成功": "",
37+
"去设置 >>": "",
3738
"同时下载任务数": "",
3839
"名称": "",
3940
"图标": "",
@@ -46,15 +47,22 @@ const zhCN = {
4647
"存储名称": "",
4748
"存储库": "",
4849
"存储桶": "",
50+
"存储状态": "",
4951
"存储类型": "",
52+
"存储类型:{driver}": "",
5053
"宫格模式": "",
5154
"密码": "",
55+
"已取消": "",
5256
"已失败": "",
5357
"已完成": "",
5458
"已选择{count}项": "",
5559
"布局": "",
5660
"帮助": "",
61+
"当前播放列表({length})": "",
62+
"执行失败": "",
63+
"执行成功": "",
5764
"拍照上传": "",
65+
"拒绝权限可能会导致本地存储无法获取到文件信息": "",
5866
"挂载目录": "",
5967
"按{sort}排序": "",
6068
"接入点": "",
@@ -77,18 +85,24 @@ const zhCN = {
7785
"最后更新于 %T": "",
7886
"未找到页面": "",
7987
"未知": "Unknown",
88+
"未知状态": "",
8089
"未知的文件类型,无法查看文件,请下载到本地查看": "",
8190
"未设置": "",
8291
"未选择": "",
92+
"本地文件的访问需要授权设备的读写权限": "",
8393
"查看详情": "",
8494
"根目录": "",
95+
"正在取消": "",
96+
"正在执行": "",
8597
"正在进行": "",
8698
"正序": "",
8799
"没有更多": "",
88100
"测试连接": "",
89101
"添加存储": "",
90102
"添加新存储": "",
91103
"清除任务": "",
104+
"源站": "",
105+
"源站格式": "",
92106
"用户": "",
93107
"目录": "",
94108
"目录权限": "",
@@ -102,6 +116,7 @@ const zhCN = {
102116
"移动": "",
103117
"移动文件到": "",
104118
"端口": "",
119+
"等待执行": "",
105120
"简介": "",
106121
"类型": "",
107122
"红枫云盘": "",

0 commit comments

Comments
 (0)