主要合入内容:

- 文件管理器分页加载、排序偏好、桌面表头排序、移动端排序菜单、Ctrl/Cmd+F搜索、Esc 关闭搜索、鼠标右滑返回上级。
- 移动端同步状态页、同步统计卡片、同步任务/累计统计事件、同步页布局更新。
- Android 相册同步默认路径改为 DCIM/Camera,下载路径改用 external_path。
- Rust sync-core 更新:Android 日志依赖、AlbumUpload/AlbumDownload、MirrorWcf 统计修复、Linux FUSE镜像挂载与读写同步支持。

- 依赖更新:external_path、fl_chart、pdfrx 升级,并修了 pdfrx 新版本的deprecated API。
- 新增文件包括:sort_options.dart、sync_page_android.dart、sync_stats_card.dart、platform/fuse.rs、sync_engine/fuse.rs。
This commit is contained in:
2026-06-04 07:11:43 +08:00
parent 5ee6ba1e28
commit b02daf1448
56 changed files with 7589 additions and 1200 deletions
+126 -25
View File
@@ -67,7 +67,7 @@ class RustSyncApi
String get codegenVersion => '2.12.0';
@override
int get rustContentHash => 264517153;
int get rustContentHash => 1656309947;
static const kDefaultExternalLibraryLoaderConfig =
ExternalLibraryLoaderConfig(
@@ -97,6 +97,8 @@ abstract class RustSyncApiApi extends BaseApi {
Future<SyncConfigFfi> crateApiFfiGetSyncConfig();
Future<SyncCumStatsFfi> crateApiFfiGetSyncCumStats();
Future<SyncStatusFfi> crateApiFfiGetSyncStatus();
Future<List<SyncTaskItemFfi>> crateApiFfiGetTaskDetail({
@@ -115,7 +117,7 @@ abstract class RustSyncApiApi extends BaseApi {
Stream<SyncEventFfi> crateApiFfiRegisterSyncEventSink();
Future<void> crateApiFfiResetSync();
Future<void> crateApiFfiResetSync({required bool deleteLocalFiles});
Future<void> crateApiFfiResumeSync();
@@ -376,7 +378,7 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
const TaskConstMeta(debugName: "get_sync_config", argNames: []);
@override
Future<SyncStatusFfi> crateApiFfiGetSyncStatus() {
Future<SyncCumStatsFfi> crateApiFfiGetSyncCumStats() {
return handler.executeNormal(
NormalTask(
callFfi: (port_) {
@@ -388,6 +390,33 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
port: port_,
);
},
codec: SseCodec(
decodeSuccessData: sse_decode_sync_cum_stats_ffi,
decodeErrorData: sse_decode_sync_error_ffi,
),
constMeta: kCrateApiFfiGetSyncCumStatsConstMeta,
argValues: [],
apiImpl: this,
),
);
}
TaskConstMeta get kCrateApiFfiGetSyncCumStatsConstMeta =>
const TaskConstMeta(debugName: "get_sync_cum_stats", argNames: []);
@override
Future<SyncStatusFfi> crateApiFfiGetSyncStatus() {
return handler.executeNormal(
NormalTask(
callFfi: (port_) {
final serializer = SseSerializer(generalizedFrbRustBinding);
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 10,
port: port_,
);
},
codec: SseCodec(
decodeSuccessData: sse_decode_sync_status_ffi,
decodeErrorData: sse_decode_sync_error_ffi,
@@ -414,7 +443,7 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 10,
funcId: 11,
port: port_,
);
},
@@ -442,7 +471,7 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 11,
funcId: 12,
port: port_,
);
},
@@ -470,7 +499,7 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 12,
funcId: 13,
port: port_,
);
},
@@ -497,7 +526,7 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 13,
funcId: 14,
port: port_,
);
},
@@ -527,7 +556,7 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 14,
funcId: 15,
port: port_,
);
},
@@ -557,7 +586,7 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 15,
funcId: 16,
port: port_,
);
},
@@ -581,15 +610,16 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
);
@override
Future<void> crateApiFfiResetSync() {
Future<void> crateApiFfiResetSync({required bool deleteLocalFiles}) {
return handler.executeNormal(
NormalTask(
callFfi: (port_) {
final serializer = SseSerializer(generalizedFrbRustBinding);
sse_encode_bool(deleteLocalFiles, serializer);
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 16,
funcId: 17,
port: port_,
);
},
@@ -598,14 +628,16 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
decodeErrorData: sse_decode_sync_error_ffi,
),
constMeta: kCrateApiFfiResetSyncConstMeta,
argValues: [],
argValues: [deleteLocalFiles],
apiImpl: this,
),
);
}
TaskConstMeta get kCrateApiFfiResetSyncConstMeta =>
const TaskConstMeta(debugName: "reset_sync", argNames: []);
TaskConstMeta get kCrateApiFfiResetSyncConstMeta => const TaskConstMeta(
debugName: "reset_sync",
argNames: ["deleteLocalFiles"],
);
@override
Future<void> crateApiFfiResumeSync() {
@@ -616,7 +648,7 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 17,
funcId: 18,
port: port_,
);
},
@@ -644,7 +676,7 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 18,
funcId: 19,
port: port_,
);
},
@@ -671,7 +703,7 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 19,
funcId: 20,
port: port_,
);
},
@@ -698,7 +730,7 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 20,
funcId: 21,
port: port_,
);
},
@@ -725,7 +757,7 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 21,
funcId: 22,
port: port_,
);
},
@@ -757,7 +789,7 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 22,
funcId: 23,
port: port_,
);
},
@@ -787,7 +819,7 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 23,
funcId: 24,
port: port_,
);
},
@@ -815,7 +847,7 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 24,
funcId: 25,
port: port_,
);
},
@@ -846,7 +878,7 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 25,
funcId: 26,
port: port_,
);
},
@@ -916,13 +948,15 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
) {
// Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>;
if (arr.length != 4)
throw Exception('unexpected arr length: expect 4 but see ${arr.length}');
if (arr.length != 6)
throw Exception('unexpected arr length: expect 6 but see ${arr.length}');
return CloudAlbumCheckResultFfi(
dcimExists: dco_decode_bool(arr[0]),
picturesExists: dco_decode_bool(arr[1]),
dcimUri: dco_decode_opt_String(arr[2]),
picturesUri: dco_decode_opt_String(arr[3]),
cameraExists: dco_decode_bool(arr[4]),
cameraUri: dco_decode_opt_String(arr[5]),
);
}
@@ -987,6 +1021,25 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
);
}
@protected
SyncCumStatsFfi dco_decode_sync_cum_stats_ffi(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>;
if (arr.length != 9)
throw Exception('unexpected arr length: expect 9 but see ${arr.length}');
return SyncCumStatsFfi(
uploaded: dco_decode_u_32(arr[0]),
downloaded: dco_decode_u_32(arr[1]),
renamed: dco_decode_u_32(arr[2]),
moved: dco_decode_u_32(arr[3]),
failed: dco_decode_u_32(arr[4]),
conflicts: dco_decode_u_32(arr[5]),
deletedLocal: dco_decode_u_32(arr[6]),
deletedRemote: dco_decode_u_32(arr[7]),
skipped: dco_decode_u_32(arr[8]),
);
}
@protected
SyncErrorFfi dco_decode_sync_error_ffi(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@@ -1265,11 +1318,15 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
var var_picturesExists = sse_decode_bool(deserializer);
var var_dcimUri = sse_decode_opt_String(deserializer);
var var_picturesUri = sse_decode_opt_String(deserializer);
var var_cameraExists = sse_decode_bool(deserializer);
var var_cameraUri = sse_decode_opt_String(deserializer);
return CloudAlbumCheckResultFfi(
dcimExists: var_dcimExists,
picturesExists: var_picturesExists,
dcimUri: var_dcimUri,
picturesUri: var_picturesUri,
cameraExists: var_cameraExists,
cameraUri: var_cameraUri,
);
}
@@ -1374,6 +1431,31 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
);
}
@protected
SyncCumStatsFfi sse_decode_sync_cum_stats_ffi(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var var_uploaded = sse_decode_u_32(deserializer);
var var_downloaded = sse_decode_u_32(deserializer);
var var_renamed = sse_decode_u_32(deserializer);
var var_moved = sse_decode_u_32(deserializer);
var var_failed = sse_decode_u_32(deserializer);
var var_conflicts = sse_decode_u_32(deserializer);
var var_deletedLocal = sse_decode_u_32(deserializer);
var var_deletedRemote = sse_decode_u_32(deserializer);
var var_skipped = sse_decode_u_32(deserializer);
return SyncCumStatsFfi(
uploaded: var_uploaded,
downloaded: var_downloaded,
renamed: var_renamed,
moved: var_moved,
failed: var_failed,
conflicts: var_conflicts,
deletedLocal: var_deletedLocal,
deletedRemote: var_deletedRemote,
skipped: var_skipped,
);
}
@protected
SyncErrorFfi sse_decode_sync_error_ffi(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -1738,6 +1820,8 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
sse_encode_bool(self.picturesExists, serializer);
sse_encode_opt_String(self.dcimUri, serializer);
sse_encode_opt_String(self.picturesUri, serializer);
sse_encode_bool(self.cameraExists, serializer);
sse_encode_opt_String(self.cameraUri, serializer);
}
@protected
@@ -1822,6 +1906,23 @@ class RustSyncApiApiImpl extends RustSyncApiApiImplPlatform
sse_encode_String(self.logLevel, serializer);
}
@protected
void sse_encode_sync_cum_stats_ffi(
SyncCumStatsFfi self,
SseSerializer serializer,
) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_u_32(self.uploaded, serializer);
sse_encode_u_32(self.downloaded, serializer);
sse_encode_u_32(self.renamed, serializer);
sse_encode_u_32(self.moved, serializer);
sse_encode_u_32(self.failed, serializer);
sse_encode_u_32(self.conflicts, serializer);
sse_encode_u_32(self.deletedLocal, serializer);
sse_encode_u_32(self.deletedRemote, serializer);
sse_encode_u_32(self.skipped, serializer);
}
@protected
void sse_encode_sync_error_ffi(SyncErrorFfi self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs