Skip to content

Commit 8ca36d8

Browse files
committed
优化
1 parent 15ae687 commit 8ca36d8

File tree

7 files changed

+75
-50
lines changed

7 files changed

+75
-50
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,4 @@ app.*.map.json
5050
/macos/DerivedData/
5151
/macos/Pods/
5252
/macos/Podfile.lock
53+
/devtools_options.yaml

build-dmg.sh

+11-4
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,17 @@ TMP_DIR=$(mktemp -d) # 创建临时目录
1414

1515
# 确保应用已经构建
1616
echo "确保macOS应用已经构建在路径:${APP_PATH}"
17-
if [ ! -d "${APP_PATH}" ]; then
18-
echo "构建macOS应用..."
19-
cd "$FLUTTER_PROJECT_PATH" || exit
20-
flutter build macos --release
17+
#if [ ! -d "${APP_PATH}" ]; then
18+
# echo "构建macOS应用..."
19+
# cd "$FLUTTER_PROJECT_PATH" || exit
20+
# flutter build macos --release
21+
#fi
22+
23+
flutter build macos --release
24+
25+
if [ "${DMG_PATH}" ]; then
26+
echo "删除已编译版本"
27+
rm -f "${DMG_PATH}"
2128
fi
2229

2330
# 复制.app文件到临时目录

lib/core/converter/converter.dart

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ class Converter {
1414
static Future<String> get baseOutputPath async =>
1515
'${Storage().getString(StorageKeys.CACHE_DIR_KEY) ?? (await getTemporaryDirectory()).path}/Convert';
1616

17-
static Future<String?> convertToFormat(String videoPath, VideoFormat format,
18-
{ProgressCallback? onProgress, FailureCallback? onFailure}) async {
17+
static convertToFormat(String videoPath, VideoFormat format,
18+
{ProgressCallback? onProgress, SuccessCallback? onSuccess, FailureCallback? onFailure}) async {
1919
Directory baseDirectory = Directory(await baseOutputPath);
2020
if (!baseDirectory.existsSync()) {
2121
baseDirectory.createSync(recursive: true);
@@ -28,8 +28,8 @@ class Converter {
2828
await FFmpegExecutor.convert(videoPath, outputPath: outputPath, onProgress: onProgress, onFailure: onFailure);
2929
if (savePath != null) {
3030
ToastUtil.success(S.current.toastConvertSuccess);
31+
onSuccess?.call(savePath);
3132
return savePath;
3233
}
33-
return null;
3434
}
3535
}

lib/model/execute_model.dart

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import 'emuns.dart';
2+
3+
class ExecuteModel {
4+
final String? key;
5+
double? progress;
6+
String? progressText;
7+
ExecuteStatus? status;
8+
String? path;
9+
10+
ExecuteModel({required this.key, required this.progress, required this.progressText, this.status, this.path});
11+
}

lib/screen/desktop/pages/convert_page.dart

+23-19
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import 'package:tubesavely/core/converter/converter.dart';
77
import 'package:tubesavely/core/ffmpeg/ffmpeg_executor.dart';
88
import 'package:tubesavely/generated/l10n.dart';
99
import 'package:tubesavely/model/emuns.dart';
10+
import 'package:tubesavely/model/execute_model.dart';
1011
import 'package:tubesavely/storage/storage.dart';
1112
import 'package:tubesavely/utils/common_util.dart';
13+
import 'package:tubesavely/utils/toast_util.dart';
1214

1315
class ConvertPage extends StatefulWidget {
1416
const ConvertPage({super.key});
@@ -20,9 +22,8 @@ class ConvertPage extends StatefulWidget {
2022
class _ConvertPageState extends State<ConvertPage> with AutomaticKeepAliveClientMixin<ConvertPage> {
2123
String videoFormat = Storage().getString(StorageKeys.CONVERT_FORMAT_KEY) ?? 'MP4';
2224
List<PlatformFile> videoList = [];
23-
Map<String, double> progressMap = {};
24-
Map<String, String> progressTextMap = {};
25-
Map<String, ExecuteStatus> statusMap = {};
25+
26+
Map<String, ExecuteModel> executeModelMap = {};
2627

2728
_pickVideo() async {
2829
FilePickerResult? result = await FilePicker.platform.pickFiles(dialogTitle: S.current.pickVideo, type: FileType.video);
@@ -35,24 +36,28 @@ class _ConvertPageState extends State<ConvertPage> with AutomaticKeepAliveClient
3536

3637
_convert(PlatformFile file) {
3738
setState(() {
38-
progressMap[file.path ?? ''] = 0;
39-
statusMap[file.path ?? ''] = ExecuteStatus.Executing;
40-
progressTextMap[file.path ?? ''] = S.current.statusConvertProgress;
39+
executeModelMap[file.path ?? ''] = ExecuteModel(
40+
key: file.path, progress: 0, progressText: S.current.statusConvertProgress, status: ExecuteStatus.Executing);
4141
});
42+
43+
ExecuteModel? executeModel = executeModelMap[file.path ?? ''];
4244
Converter.convertToFormat(
4345
file.path ?? '', VideoFormat.values.byName(videoFormat == '3GP' ? '_3gp' : videoFormat.toLowerCase()),
4446
onProgress: (type, value) {
4547
setState(() {
46-
progressMap[file.path ?? ''] = value;
47-
progressTextMap[file.path ?? ''] = S.current.statusConvertProgress;
48+
executeModel?.progress = value;
49+
executeModel?.progressText = S.current.statusConvertProgress;
4850
if (value >= 100) {
49-
statusMap[file.path ?? ''] = ExecuteStatus.Success;
50-
progressTextMap[file.path ?? ''] = S.current.statusComplete;
51+
executeModel?.status = ExecuteStatus.Success;
52+
executeModel?.progressText = S.current.statusComplete;
5153
}
5254
});
55+
}, onSuccess: (path) {
56+
executeModel?.path = path;
5357
}, onFailure: (error) {
54-
statusMap[file.path ?? ''] = ExecuteStatus.Idle;
55-
progressTextMap[file.path ?? ''] = S.current.statusConvertFailed;
58+
executeModel?.status = ExecuteStatus.Idle;
59+
executeModel?.progressText = S.current.statusConvertFailed;
60+
ToastUtil.error(S.current.statusConvertFailed);
5661
});
5762
}
5863

@@ -188,7 +193,7 @@ class _ConvertPageState extends State<ConvertPage> with AutomaticKeepAliveClient
188193
children: [
189194
Expanded(
190195
child: LinearProgressIndicator(
191-
value: (progressMap[file.path ?? ''] ?? 0) / 100,
196+
value: (executeModelMap[file.path]?.progress ?? 0) / 100,
192197
minHeight: 2,
193198
color: Theme.of(context).primaryColor,
194199
borderRadius: BorderRadius.circular(50),
@@ -197,15 +202,16 @@ class _ConvertPageState extends State<ConvertPage> with AutomaticKeepAliveClient
197202
const SizedBox(
198203
width: 10,
199204
),
200-
Text('${progressTextMap[file.path ?? ''] ?? ''} ${(progressMap[file.path ?? '']?.toStringAsFixed(2) ?? 0)}%',
205+
Text(
206+
'${executeModelMap[file.path]?.progressText ?? ''} ${(executeModelMap[file.path]?.progress?.toStringAsFixed(2) ?? 0)}%',
201207
style: TextStyle(fontSize: 12, color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6)))
202208
],
203209
)
204210
],
205211
)),
206212
Row(
207213
children: [
208-
statusMap[file.path ?? ''] == ExecuteStatus.Executing
214+
executeModelMap[file.path]?.status == ExecuteStatus.Executing
209215
? Container(
210216
width: 40,
211217
height: 40,
@@ -224,7 +230,7 @@ class _ConvertPageState extends State<ConvertPage> with AutomaticKeepAliveClient
224230
)),
225231
IconButton(
226232
onPressed: () async {
227-
CommonUtil.openDesktopDirectory((await Converter.baseOutputPath ?? ''));
233+
CommonUtil.openDesktopDirectory(executeModelMap[file.path]?.path ?? (await Converter.baseOutputPath ?? ''));
228234
},
229235
icon: const Icon(
230236
Icons.folder_open,
@@ -234,9 +240,7 @@ class _ConvertPageState extends State<ConvertPage> with AutomaticKeepAliveClient
234240
onPressed: () {
235241
setState(() {
236242
videoList.remove(file);
237-
statusMap.remove(file.path ?? '');
238-
progressMap.remove(file.path ?? '');
239-
progressTextMap.remove(file.path ?? '');
243+
executeModelMap.remove(file.path);
240244
});
241245
},
242246
icon: const Icon(

lib/screen/desktop/pages/download_page.dart

+25-23
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:tubesavely/extension/extension.dart';
66
import 'package:tubesavely/generated/l10n.dart';
77
import 'package:tubesavely/http/http_request.dart';
88
import 'package:tubesavely/model/emuns.dart';
9+
import 'package:tubesavely/model/execute_model.dart';
910
import 'package:tubesavely/model/pair.dart';
1011
import 'package:tubesavely/model/video_model.dart';
1112
import 'package:tubesavely/storage/storage.dart';
@@ -25,9 +26,7 @@ class _DownloadPageState extends State<DownloadPage> with AutomaticKeepAliveClie
2526
List<VideoModel> videoModelList = [];
2627
List<String> taskList = [];
2728

28-
Map<String, double> progressMap = {};
29-
Map<String, String> progressTextMap = {};
30-
Map<String, ExecuteStatus> statusMap = {};
29+
Map<String, ExecuteModel> executeModelMap = {};
3130

3231
void _extractVideo(String url) async {
3332
if (!url.isValidUrl()) {
@@ -72,9 +71,8 @@ class _DownloadPageState extends State<DownloadPage> with AutomaticKeepAliveClie
7271

7372
void _download(VideoModel model) async {
7473
setState(() {
75-
progressMap[model.original_url ?? ''] = 0;
76-
statusMap[model.original_url ?? ''] = ExecuteStatus.Executing;
77-
progressTextMap[model.original_url ?? ''] = S.current.statusDownloadProgress;
74+
executeModelMap[model.original_url ?? ''] = ExecuteModel(
75+
key: model.original_url, progress: 0, progressText: S.current.statusDownloadProgress, status: ExecuteStatus.Executing);
7876
});
7977

8078
final quality = Storage().getString(StorageKeys.DOWNLOAD_QUALITY_KEY);
@@ -83,28 +81,33 @@ class _DownloadPageState extends State<DownloadPage> with AutomaticKeepAliveClie
8381
FormatModel? target = videoList?.firstWhere((item) => VideoResolutionUtil.format(item.resolution ?? '') == quality,
8482
orElse: () => videoList.first);
8583

84+
ExecuteModel? executeModel = executeModelMap[model.original_url ?? ""];
8685
Downloader.start(target?.url ?? '', model.title ?? '',
8786
audioUrl: audioList?.isEmpty == true ? null : audioList?[1].url,
8887
resolution: VideoResolutionUtil.format(target?.resolution ?? ''), onProgress: (type, value) {
8988
setState(() {
90-
progressMap[model.original_url ?? ''] = value;
89+
executeModel?.progress = value;
9190
if (type == ProgressType.download) {
92-
progressTextMap[model.original_url ?? ''] = S.current.statusDownloadProgress;
91+
executeModel?.progressText = S.current.statusDownloadProgress;
9392
} else if (type == ProgressType.recode) {
94-
progressTextMap[model.original_url ?? ''] = S.current.statusRecodeProgress;
93+
executeModel?.progressText = S.current.statusRecodeProgress;
9594
} else if (type == ProgressType.merge) {
96-
progressTextMap[model.original_url ?? ''] = S.current.statusMergeProgress;
95+
executeModel?.progressText = S.current.statusMergeProgress;
9796
}
9897
if (value >= 100) {
99-
statusMap[model.original_url ?? ''] = ExecuteStatus.Success;
100-
progressTextMap[model.original_url ?? ''] = S.current.statusComplete;
98+
executeModel?.status = ExecuteStatus.Success;
99+
executeModel?.progressText = S.current.statusComplete;
101100
}
102101
});
102+
}, onSuccess: (path) {
103+
executeModel?.path = path;
104+
executeModel?.status = ExecuteStatus.Success;
103105
}, onFailure: (error) {
104106
setState(() {
105-
statusMap[model.original_url ?? ''] = ExecuteStatus.Idle;
106-
progressMap[model.original_url ?? ''] = 0;
107-
progressTextMap[model.original_url ?? ''] = S.current.statusFailed;
107+
executeModel?.status = ExecuteStatus.Idle;
108+
executeModel?.progress = 0;
109+
executeModel?.progressText = S.current.statusFailed;
110+
ToastUtil.error(S.current.statusFailed);
108111
});
109112
});
110113
}
@@ -147,7 +150,7 @@ class _DownloadPageState extends State<DownloadPage> with AutomaticKeepAliveClie
147150
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(50))),
148151
onPressed: () async {
149152
videoModelList.forEach((model) async {
150-
if (statusMap[model.original_url ?? ''] == null) {
153+
if (executeModelMap[model.original_url]?.status == null) {
151154
_download(model);
152155
}
153156
});
@@ -250,7 +253,7 @@ class _DownloadPageState extends State<DownloadPage> with AutomaticKeepAliveClie
250253
children: [
251254
Expanded(
252255
child: LinearProgressIndicator(
253-
value: (progressMap[model.original_url] ?? 0) / 100,
256+
value: (executeModelMap[model.original_url]?.progress ?? 0) / 100,
254257
minHeight: 2,
255258
color: Theme.of(context).primaryColor,
256259
borderRadius: BorderRadius.circular(50),
@@ -260,15 +263,15 @@ class _DownloadPageState extends State<DownloadPage> with AutomaticKeepAliveClie
260263
width: 10,
261264
),
262265
Text(
263-
'${progressTextMap[model.original_url] ?? ''} ${(progressMap[model.original_url]?.toStringAsFixed(2) ?? 0)}%',
266+
'${executeModelMap[model.original_url]?.progressText ?? ''} ${(executeModelMap[model.original_url]?.progress?.toStringAsFixed(2) ?? 0)}%',
264267
style: TextStyle(fontSize: 12, color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6)))
265268
],
266269
)
267270
],
268271
)),
269272
Row(
270273
children: [
271-
statusMap[model.original_url ?? ''] == ExecuteStatus.Executing
274+
executeModelMap[model.original_url]?.status == ExecuteStatus.Executing
272275
? Container(
273276
width: 40,
274277
height: 40,
@@ -290,7 +293,8 @@ class _DownloadPageState extends State<DownloadPage> with AutomaticKeepAliveClie
290293
)),
291294
IconButton(
292295
onPressed: () async {
293-
CommonUtil.openDesktopDirectory(Storage().getString(StorageKeys.CACHE_DIR_KEY) ?? '');
296+
CommonUtil.openDesktopDirectory(
297+
executeModelMap[model.original_url]?.path ?? Storage().getString(StorageKeys.CACHE_DIR_KEY) ?? '');
294298
},
295299
icon: const Icon(
296300
Icons.folder_open,
@@ -300,9 +304,7 @@ class _DownloadPageState extends State<DownloadPage> with AutomaticKeepAliveClie
300304
onPressed: () {
301305
setState(() {
302306
videoModelList.remove(model);
303-
statusMap.remove(model.original_url ?? '');
304-
progressMap.remove(model.original_url ?? '');
305-
progressTextMap.remove(model.original_url ?? '');
307+
executeModelMap.remove(model.original_url);
306308
taskList.remove(model.original_url);
307309
});
308310
},

lib/utils/common_util.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class CommonUtil {
2828

2929
static void openDesktopDirectory(String path) async {
3030
if (Platform.isMacOS) {
31-
_open('open', ['-R', path.padRight(path.length + 1, path)]);
31+
_open('open', ['-R', path.padRight(path.length + 1, '/')]);
3232
} else if (Platform.isWindows) {
3333
_open('explorer', [path]);
3434
} else if (Platform.isLinux) {

0 commit comments

Comments
 (0)