Skip to content

Commit

Permalink
perf: faster backup dialog opening
Browse files Browse the repository at this point in the history
by runnning calculations on isolates
  • Loading branch information
MSOB7YY committed Jan 22, 2024
1 parent f227d05 commit 96a768b
Show file tree
Hide file tree
Showing 2 changed files with 166 additions and 80 deletions.
36 changes: 34 additions & 2 deletions lib/core/extensions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -437,13 +437,26 @@ extension DirectoryUtils on Directory {
'recursive': recursive,
'followLinks': followLinks,
};
final res = await compute(_listAllIsolate, params);
return res;
return await compute(_listAllIsolate, params);
} catch (e) {
printy(e, isError: true);
return [];
}
}

Future<int?> getTotalSize({bool recursive = false, bool followLinks = true}) async {
try {
final params = {
'dirPath': path,
'recursive': recursive,
'followLinks': followLinks,
};
return await compute(_getDirSizeIsolate, params);
} catch (e) {
printy(e, isError: true);
return null;
}
}
}

List<FileSystemEntity> _listAllIsolate(Map params) {
Expand All @@ -453,7 +466,26 @@ List<FileSystemEntity> _listAllIsolate(Map params) {
return Directory(dirPath).listSync(recursive: recursive, followLinks: followLinks);
}

int _getDirSizeIsolate(Map params) {
final dirPath = params['dirPath'] as String;
final recursive = params['recursive'] as bool;
final followLinks = params['followLinks'] as bool;
int size = 0;
Directory(dirPath).listSync(recursive: recursive, followLinks: followLinks).loop((e, index) {
size += (e is File ? File(e.path).fileSizeSync() ?? 0 : 0);
});
return size;
}

extension FileUtils on File {
Future<int?> fileSize() async {
try {
return await length();
} catch (e) {
return null;
}
}

int? fileSizeSync() {
try {
return lengthSync();
Expand Down
210 changes: 132 additions & 78 deletions lib/ui/widgets/settings/backup_restore_settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -176,20 +176,67 @@ class BackupAndRestore extends SettingSubpageProvider {
}
}

int doIt(List<String> forWhat) {
int totalSize = 0;
forWhat.loop((e, _) {
if (FileSystemEntity.typeSync(e) == FileSystemEntityType.file) {
totalSize += File(e).fileSizeSync() ?? 0;
} else if (FileSystemEntity.typeSync(e) == FileSystemEntityType.directory) {
int size = 0;
Directory(e).listSyncSafe().loop((e, index) {
size += (e is File ? File(e.path).fileSizeSync() ?? 0 : 0);
});
totalSize += size;
final totalFiles = [
AppPaths.TRACKS,
AppPaths.TRACKS_STATS,
AppPaths.TOTAL_LISTEN_TIME,
AppPaths.VIDEOS_CACHE,
AppPaths.VIDEOS_LOCAL,
AppPaths.FAVOURITES_PLAYLIST,
AppPaths.SETTINGS,
AppPaths.LATEST_QUEUE,
AppPaths.YT_LIKES_PLAYLIST,
];

final totalDirs = [
AppDirs.PLAYLISTS,
AppDirs.HISTORY_PLAYLIST,
AppDirs.LYRICS,
AppDirs.QUEUES,
AppDirs.PALETTES,
AppDirs.VIDEOS_CACHE,
AppDirs.AUDIOS_CACHE,
AppDirs.ARTWORKS,
AppDirs.THUMBNAILS,
AppDirs.YT_DOWNLOAD_TASKS,
AppDirs.YT_STATS,
AppDirs.YT_PLAYLISTS,
AppDirs.YT_HISTORY_PLAYLIST,
AppDirs.YT_PALETTES,
AppDirs.YT_THUMBNAILS,
AppDirs.YT_THUMBNAILS_CHANNELS,
AppDirs.YT_METADATA,
AppDirs.YT_METADATA_CHANNELS,
AppDirs.YT_METADATA_COMMENTS,
];

final sizesMap = <String, int>{}.obs;
void fillFilesSize() async {
for (final item in totalFiles) {
sizesMap[item] = await File(item).fileSize() ?? 0;
}
}

void fillDirsSize() async {
for (final item in totalDirs) {
sizesMap[item] = await Directory(item).getTotalSize() ?? 0;
}
}

fillFilesSize();
fillDirsSize();

(int, bool) getItemsSize(List<String> items, Map<String, int> map) {
int s = 0;
bool hasUnknown = false;
items.loop((e, _) {
if (map[e] == null) {
hasUnknown = true;
} else {
s += map[e]!;
}
});
return totalSize;
return (s, hasUnknown);
}

Widget getItemWidget({
Expand All @@ -200,83 +247,90 @@ class BackupAndRestore extends SettingSubpageProvider {
bool youtubeForceFollowItems = false,
required List<String> youtubeItems,
}) {
final totalSizeLocal = doIt(items);
final totalSizeYoutube = doIt(youtubeItems);

return Obx(
() {
final isLocalIconChecked = isActive(items);
final isYoutubeIconChecked = youtubeForceFollowItems
? isActive(items)
: !youtubeAvailable
? false
: youtubeItems.isEmpty
final localRes = getItemsSize(items, sizesMap);
final ytRes = getItemsSize(youtubeItems, sizesMap);
final localSize = localRes.$1;
final ytSize = ytRes.$1;
final localUnknown = localRes.$2;
final ytUnknown = ytRes.$2;
return Obx(
() {
final isLocalIconChecked = isActive(items);
final isYoutubeIconChecked = youtubeForceFollowItems
? isActive(items)
: !youtubeAvailable
? false
: isActive(youtubeItems);
return Row(
children: [
Expanded(
child: ListTileWithCheckMark(
active: isLocalIconChecked,
titleWidget: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: context.textTheme.displayMedium,
),
Row(
: youtubeItems.isEmpty
? false
: isActive(youtubeItems);
return Row(
children: [
Expanded(
child: ListTileWithCheckMark(
active: isLocalIconChecked,
titleWidget: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AnimatedOpacity(
duration: const Duration(milliseconds: 200),
opacity: isLocalIconChecked ? 1.0 : 0.5,
child: Text(
"(${totalSizeLocal.fileSizeFormatted})",
style: context.textTheme.displaySmall,
),
Text(
title,
style: context.textTheme.displayMedium,
),
if (totalSizeYoutube > 0)
AnimatedOpacity(
duration: const Duration(milliseconds: 200),
opacity: isYoutubeIconChecked ? 1.0 : 0.5,
child: Text(
" + (${totalSizeYoutube.fileSizeFormatted})",
style: context.textTheme.displaySmall,
Row(
children: [
AnimatedOpacity(
duration: const Duration(milliseconds: 200),
opacity: isLocalIconChecked ? 1.0 : 0.5,
child: Text(
"(${localSize.fileSizeFormatted})${localUnknown ? '?' : ''}",
style: context.textTheme.displaySmall,
),
),
),
if (ytSize > 0 || ytUnknown)
AnimatedOpacity(
duration: const Duration(milliseconds: 200),
opacity: isYoutubeIconChecked ? 1.0 : 0.5,
child: Text(
" + (${ytSize.fileSizeFormatted})${ytUnknown ? '?' : ''}",
style: context.textTheme.displaySmall,
),
),
],
),
],
),
],
icon: icon,
onTap: () => onItemTap(items),
),
),
icon: icon,
onTap: () => onItemTap(items),
),
),
const SizedBox(width: 8.0),
AnimatedOpacity(
duration: const Duration(milliseconds: 300),
opacity: youtubeAvailable ? 1.0 : 0.6,
child: NamidaIconButton(
tooltip: lang.YOUTUBE,
horizontalPadding: 0.0,
icon: null,
onPressed: () {
if (youtubeAvailable) {
onItemTap(youtubeItems);
}
},
child: StackedIcon(
iconSize: 28.0,
baseIcon: Broken.video_square,
smallChild: NamidaCheckMark(
size: 12.0,
active: isYoutubeIconChecked,
const SizedBox(width: 8.0),
AnimatedOpacity(
duration: const Duration(milliseconds: 300),
opacity: youtubeAvailable ? 1.0 : 0.6,
child: NamidaIconButton(
tooltip: lang.YOUTUBE,
horizontalPadding: 0.0,
icon: null,
onPressed: () {
if (youtubeAvailable) {
onItemTap(youtubeItems);
}
},
child: StackedIcon(
iconSize: 28.0,
baseIcon: Broken.video_square,
smallChild: NamidaCheckMark(
size: 12.0,
active: isYoutubeIconChecked,
),
),
),
),
),
),
const SizedBox(width: 8.0),
],
const SizedBox(width: 8.0),
],
);
},
);
},
);
Expand Down

0 comments on commit 96a768b

Please sign in to comment.