restore jobTable state mode
This commit is contained in:
parent
b7a0436aa3
commit
a2f82b6ea6
flutter/lib
@ -157,171 +157,163 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
/// transfer status list
|
/// transfer status list
|
||||||
/// watch transfer status
|
/// watch transfer status
|
||||||
Widget statusList() {
|
Widget statusList() {
|
||||||
|
statusListView() => Obx(() => ListView.builder(
|
||||||
|
controller: ScrollController(),
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
final item = jobController.jobTable[index];
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 5),
|
||||||
|
child: generateCard(
|
||||||
|
Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Transform.rotate(
|
||||||
|
angle: item.isRemoteToLocal ? pi : 0,
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
"assets/arrow.svg",
|
||||||
|
color: Theme.of(context).tabBarTheme.labelColor,
|
||||||
|
),
|
||||||
|
).paddingOnly(left: 15),
|
||||||
|
const SizedBox(
|
||||||
|
width: 16.0,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Tooltip(
|
||||||
|
waitDuration: Duration(milliseconds: 500),
|
||||||
|
message: item.jobName,
|
||||||
|
child: Text(
|
||||||
|
item.fileName,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
).paddingSymmetric(vertical: 10),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'${translate("Total")} ${readableFileSize(item.totalSize.toDouble())}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: MyTheme.darkGray,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Offstage(
|
||||||
|
offstage: item.state != JobState.inProgress,
|
||||||
|
child: Text(
|
||||||
|
'${translate("Speed")} ${readableFileSize(item.speed)}/s',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: MyTheme.darkGray,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Offstage(
|
||||||
|
offstage: item.state == JobState.inProgress,
|
||||||
|
child: Text(
|
||||||
|
translate(
|
||||||
|
item.display(),
|
||||||
|
),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: MyTheme.darkGray,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Offstage(
|
||||||
|
offstage: item.state != JobState.inProgress,
|
||||||
|
child: LinearPercentIndicator(
|
||||||
|
padding: EdgeInsets.only(right: 15),
|
||||||
|
animateFromLastPercent: true,
|
||||||
|
center: Text(
|
||||||
|
'${(item.finishedSize / item.totalSize * 100).toStringAsFixed(0)}%',
|
||||||
|
),
|
||||||
|
barRadius: Radius.circular(15),
|
||||||
|
percent: item.finishedSize / item.totalSize,
|
||||||
|
progressColor: MyTheme.accent,
|
||||||
|
backgroundColor: Theme.of(context).hoverColor,
|
||||||
|
lineHeight: kDesktopFileTransferRowHeight,
|
||||||
|
).paddingSymmetric(vertical: 15),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Offstage(
|
||||||
|
offstage: item.state != JobState.paused,
|
||||||
|
child: MenuButton(
|
||||||
|
onPressed: () {
|
||||||
|
jobController.resumeJob(item.id);
|
||||||
|
},
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
"assets/refresh.svg",
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
color: MyTheme.accent,
|
||||||
|
hoverColor: MyTheme.accent80,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
MenuButton(
|
||||||
|
padding: EdgeInsets.only(right: 15),
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
"assets/close.svg",
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
jobController.jobTable.removeAt(index);
|
||||||
|
jobController.cancelJob(item.id);
|
||||||
|
},
|
||||||
|
color: MyTheme.accent,
|
||||||
|
hoverColor: MyTheme.accent80,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).paddingSymmetric(vertical: 10),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: jobController.jobTable.length,
|
||||||
|
));
|
||||||
|
|
||||||
return PreferredSize(
|
return PreferredSize(
|
||||||
preferredSize: const Size(200, double.infinity),
|
preferredSize: const Size(200, double.infinity),
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: const EdgeInsets.only(top: 16.0, bottom: 16.0, right: 16.0),
|
margin: const EdgeInsets.only(top: 16.0, bottom: 16.0, right: 16.0),
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: jobController.jobTable.isEmpty
|
child: Obx(
|
||||||
? generateCard(
|
() => jobController.jobTable.isEmpty
|
||||||
Center(
|
? generateCard(
|
||||||
child: Column(
|
Center(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
child: Column(
|
||||||
children: [
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
SvgPicture.asset(
|
children: [
|
||||||
"assets/transfer.svg",
|
SvgPicture.asset(
|
||||||
color: Theme.of(context).tabBarTheme.labelColor,
|
"assets/transfer.svg",
|
||||||
height: 40,
|
color: Theme.of(context).tabBarTheme.labelColor,
|
||||||
).paddingOnly(bottom: 10),
|
height: 40,
|
||||||
Text(
|
).paddingOnly(bottom: 10),
|
||||||
translate("No transfers in progress"),
|
Text(
|
||||||
textAlign: TextAlign.center,
|
translate("No transfers in progress"),
|
||||||
textScaleFactor: 1.20,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(
|
textScaleFactor: 1.20,
|
||||||
color: Theme.of(context).tabBarTheme.labelColor),
|
style: TextStyle(
|
||||||
|
color:
|
||||||
|
Theme.of(context).tabBarTheme.labelColor),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
)
|
||||||
),
|
: statusListView(),
|
||||||
)
|
)),
|
||||||
: Obx(
|
|
||||||
() => ListView.builder(
|
|
||||||
controller: ScrollController(),
|
|
||||||
itemBuilder: (BuildContext context, int index) {
|
|
||||||
final item = jobController.jobTable[index];
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.only(bottom: 5),
|
|
||||||
child: generateCard(
|
|
||||||
Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Transform.rotate(
|
|
||||||
angle: item.isRemoteToLocal ? pi : 0,
|
|
||||||
child: SvgPicture.asset(
|
|
||||||
"assets/arrow.svg",
|
|
||||||
color: Theme.of(context)
|
|
||||||
.tabBarTheme
|
|
||||||
.labelColor,
|
|
||||||
),
|
|
||||||
).paddingOnly(left: 15),
|
|
||||||
const SizedBox(
|
|
||||||
width: 16.0,
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
crossAxisAlignment:
|
|
||||||
CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Tooltip(
|
|
||||||
waitDuration:
|
|
||||||
Duration(milliseconds: 500),
|
|
||||||
message: item.jobName,
|
|
||||||
child: Text(
|
|
||||||
item.fileName,
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
).paddingSymmetric(vertical: 10),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
'${translate("Total")} ${readableFileSize(item.totalSize.toDouble())}',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
color: MyTheme.darkGray,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Offstage(
|
|
||||||
offstage:
|
|
||||||
item.state != JobState.inProgress,
|
|
||||||
child: Text(
|
|
||||||
'${translate("Speed")} ${readableFileSize(item.speed)}/s',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
color: MyTheme.darkGray,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Offstage(
|
|
||||||
offstage:
|
|
||||||
item.state == JobState.inProgress,
|
|
||||||
child: Text(
|
|
||||||
translate(
|
|
||||||
item.display(),
|
|
||||||
),
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
color: MyTheme.darkGray,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Offstage(
|
|
||||||
offstage:
|
|
||||||
item.state != JobState.inProgress,
|
|
||||||
child: LinearPercentIndicator(
|
|
||||||
padding: EdgeInsets.only(right: 15),
|
|
||||||
animateFromLastPercent: true,
|
|
||||||
center: Text(
|
|
||||||
'${(item.finishedSize / item.totalSize * 100).toStringAsFixed(0)}%',
|
|
||||||
),
|
|
||||||
barRadius: Radius.circular(15),
|
|
||||||
percent: item.finishedSize /
|
|
||||||
item.totalSize,
|
|
||||||
progressColor: MyTheme.accent,
|
|
||||||
backgroundColor:
|
|
||||||
Theme.of(context).hoverColor,
|
|
||||||
lineHeight:
|
|
||||||
kDesktopFileTransferRowHeight,
|
|
||||||
).paddingSymmetric(vertical: 15),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
|
||||||
children: [
|
|
||||||
Offstage(
|
|
||||||
offstage: item.state != JobState.paused,
|
|
||||||
child: MenuButton(
|
|
||||||
onPressed: () {
|
|
||||||
jobController.resumeJob(item.id);
|
|
||||||
},
|
|
||||||
child: SvgPicture.asset(
|
|
||||||
"assets/refresh.svg",
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
color: MyTheme.accent,
|
|
||||||
hoverColor: MyTheme.accent80,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
MenuButton(
|
|
||||||
padding: EdgeInsets.only(right: 15),
|
|
||||||
child: SvgPicture.asset(
|
|
||||||
"assets/close.svg",
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
jobController.jobTable.removeAt(index);
|
|
||||||
jobController.cancelJob(item.id);
|
|
||||||
},
|
|
||||||
color: MyTheme.accent,
|
|
||||||
hoverColor: MyTheme.accent80,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
).paddingSymmetric(vertical: 10),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
itemCount: jobController.jobTable.length,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -418,8 +410,7 @@ class _FileManagerViewState extends State<FileManagerView> {
|
|||||||
},
|
},
|
||||||
onExit: (evt) =>
|
onExit: (evt) =>
|
||||||
widget._mouseFocusScope.value = MouseFocusScope.none,
|
widget._mouseFocusScope.value = MouseFocusScope.none,
|
||||||
child: _buildFileList(
|
child: _buildFileList(context, _fileListScrollController),
|
||||||
context, isLocal, _fileListScrollController),
|
|
||||||
))
|
))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -864,7 +855,7 @@ class _FileManagerViewState extends State<FileManagerView> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildFileList(
|
Widget _buildFileList(
|
||||||
BuildContext context, bool isLocal, ScrollController scrollController) {
|
BuildContext context, ScrollController scrollController) {
|
||||||
final fd = controller.directory.value;
|
final fd = controller.directory.value;
|
||||||
final entries = fd.entries;
|
final entries = fd.entries;
|
||||||
|
|
||||||
@ -1044,7 +1035,7 @@ class _FileManagerViewState extends State<FileManagerView> {
|
|||||||
// Header
|
// Header
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(child: _buildFileBrowserHeader(context, isLocal)),
|
Expanded(child: _buildFileBrowserHeader(context)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
// Body
|
// Body
|
||||||
@ -1139,7 +1130,7 @@ class _FileManagerViewState extends State<FileManagerView> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildFileBrowserHeader(BuildContext context, bool isLocal) {
|
Widget _buildFileBrowserHeader(BuildContext context) {
|
||||||
final padding = EdgeInsets.all(1.0);
|
final padding = EdgeInsets.all(1.0);
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: kDesktopFileTransferHeaderHeight,
|
height: kDesktopFileTransferHeaderHeight,
|
||||||
@ -1147,7 +1138,7 @@ class _FileManagerViewState extends State<FileManagerView> {
|
|||||||
children: [
|
children: [
|
||||||
Obx(
|
Obx(
|
||||||
() => headerItemFunc(
|
() => headerItemFunc(
|
||||||
_nameColWidth.value, SortBy.name, translate("Name"), isLocal),
|
_nameColWidth.value, SortBy.name, translate("Name")),
|
||||||
),
|
),
|
||||||
DraggableDivider(
|
DraggableDivider(
|
||||||
axis: Axis.vertical,
|
axis: Axis.vertical,
|
||||||
@ -1160,7 +1151,7 @@ class _FileManagerViewState extends State<FileManagerView> {
|
|||||||
),
|
),
|
||||||
Obx(
|
Obx(
|
||||||
() => headerItemFunc(_modifiedColWidth.value, SortBy.modified,
|
() => headerItemFunc(_modifiedColWidth.value, SortBy.modified,
|
||||||
translate("Modified"), isLocal),
|
translate("Modified")),
|
||||||
),
|
),
|
||||||
DraggableDivider(
|
DraggableDivider(
|
||||||
axis: Axis.vertical,
|
axis: Axis.vertical,
|
||||||
@ -1172,16 +1163,13 @@ class _FileManagerViewState extends State<FileManagerView> {
|
|||||||
_modifiedColWidth.value));
|
_modifiedColWidth.value));
|
||||||
},
|
},
|
||||||
padding: padding),
|
padding: padding),
|
||||||
Expanded(
|
Expanded(child: headerItemFunc(null, SortBy.size, translate("Size")))
|
||||||
child:
|
|
||||||
headerItemFunc(null, SortBy.size, translate("Size"), isLocal))
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget headerItemFunc(
|
Widget headerItemFunc(double? width, SortBy sortBy, String name) {
|
||||||
double? width, SortBy sortBy, String name, bool isLocal) {
|
|
||||||
final headerTextStyle =
|
final headerTextStyle =
|
||||||
Theme.of(context).dataTableTheme.headingTextStyle ?? TextStyle();
|
Theme.of(context).dataTableTheme.headingTextStyle ?? TextStyle();
|
||||||
return ObxValue<Rx<bool?>>(
|
return ObxValue<Rx<bool?>>(
|
||||||
@ -1222,7 +1210,7 @@ class _FileManagerViewState extends State<FileManagerView> {
|
|||||||
),
|
),
|
||||||
), () {
|
), () {
|
||||||
if (controller.sortBy.value == sortBy) {
|
if (controller.sortBy.value == sortBy) {
|
||||||
return controller.sortAscending;
|
return controller.sortAscending.obs;
|
||||||
} else {
|
} else {
|
||||||
return Rx<bool?>(null);
|
return Rx<bool?>(null);
|
||||||
}
|
}
|
||||||
|
@ -208,7 +208,7 @@ class FileController {
|
|||||||
|
|
||||||
final history = RxList<String>.empty(growable: true);
|
final history = RxList<String>.empty(growable: true);
|
||||||
final sortBy = SortBy.name.obs;
|
final sortBy = SortBy.name.obs;
|
||||||
final sortAscending = true.obs;
|
var sortAscending = true;
|
||||||
final JobController jobController;
|
final JobController jobController;
|
||||||
final OverlayDialogManager? dialogManager;
|
final OverlayDialogManager? dialogManager;
|
||||||
|
|
||||||
@ -285,7 +285,7 @@ class FileController {
|
|||||||
|
|
||||||
void changeSortStyle(SortBy sort, {bool? isLocal, bool ascending = true}) {
|
void changeSortStyle(SortBy sort, {bool? isLocal, bool ascending = true}) {
|
||||||
sortBy.value = sort;
|
sortBy.value = sort;
|
||||||
sortAscending.value = ascending;
|
sortAscending = ascending;
|
||||||
directory.value.changeSortStyle(sort, ascending: ascending);
|
directory.value.changeSortStyle(sort, ascending: ascending);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -592,7 +592,7 @@ class FileController {
|
|||||||
|
|
||||||
class JobController {
|
class JobController {
|
||||||
static final JobID jobID = JobID();
|
static final JobID jobID = JobID();
|
||||||
final jobTable = RxList<JobProgress>.empty(growable: true);
|
final jobTable = List<JobProgress>.empty(growable: true).obs;
|
||||||
final jobResultListener = JobResultListener<Map<String, dynamic>>();
|
final jobResultListener = JobResultListener<Map<String, dynamic>>();
|
||||||
final GetSessionID getSessionID;
|
final GetSessionID getSessionID;
|
||||||
String get sessionID => getSessionID();
|
String get sessionID => getSessionID();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user