Skip to content

Commit

Permalink
feat: new sort for cache videos: oldest watch
Browse files Browse the repository at this point in the history
chore: some other ui improvements
MSOB7YY committed Aug 5, 2023
1 parent 6d71267 commit 71a0a82
Showing 8 changed files with 126 additions and 73 deletions.
1 change: 1 addition & 0 deletions assets/language/translations/en_US.json
Original file line number Diff line number Diff line change
@@ -291,6 +291,7 @@
"NO_TRACKS_IN_HISTORY": "You don't have enough tracks in history.",
"NUMBER_OF_TRACKS": "Number of Tracks",
"OF": "of",
"OLDEST_WATCH": "Oldest Watch",
"OPEN_YOUTUBE_LINK": "Open Youtube Link",
"OR": "or",
"PALETTE": "Palette",
1 change: 1 addition & 0 deletions lib/controller/indexer_controller.dart
Original file line number Diff line number Diff line change
@@ -733,6 +733,7 @@ class Indexer {
if (availableDirs != null && !forceReCheck) {
return await availableDirs!.future;
} else {
availableDirs = null; // for when forceReCheck enabled.
availableDirs = Completer<Map<Directory, bool>>();

final allAvailableDirectories = <Directory, bool>{};
4 changes: 2 additions & 2 deletions lib/controller/queue_controller.dart
Original file line number Diff line number Diff line change
@@ -112,7 +112,7 @@ class QueueController {

/// Only use when updating missing track.
Future<void> replaceTrackInAllQueues(Track oldTrack, Track newTrack) async {
final queuesToSave = <Queue>[];
final queuesToSave = <Queue>{};
queuesMap.value.entries.toList().loop((entry, index) {
final q = entry.value;
q.tracks.replaceItems(
@@ -121,7 +121,7 @@ class QueueController {
onMatch: () => queuesToSave.add(q),
);
});
await queuesToSave.loopFuture((q, index) async {
await queuesToSave.toList().loopFuture((q, index) async {
_updateMap(q);
await _saveQueueToStorage(q);
});
1 change: 1 addition & 0 deletions lib/core/translations/keys.dart
Original file line number Diff line number Diff line change
@@ -294,6 +294,7 @@ class LanguageKeys {
late String NOTE;
late String NUMBER_OF_TRACKS;
late String OF;
late String OLDEST_WATCH;
late String OPEN_YOUTUBE_LINK;
late String OR;
late String PALETTE;
2 changes: 2 additions & 0 deletions lib/core/translations/language.dart
Original file line number Diff line number Diff line change
@@ -359,6 +359,7 @@ class Language extends LanguageKeys {
NOTE = getKey("NOTE");
NUMBER_OF_TRACKS = getKey("NUMBER_OF_TRACKS");
OF = getKey("OF");
OLDEST_WATCH = getKey("OLDEST_WATCH");
OPEN_YOUTUBE_LINK = getKey("OPEN_YOUTUBE_LINK");
OR = getKey("OR");
PALETTE = getKey("PALETTE");
@@ -567,3 +568,4 @@ class Language extends LanguageKeys {




2 changes: 1 addition & 1 deletion lib/ui/widgets/custom_widgets.dart
Original file line number Diff line number Diff line change
@@ -674,7 +674,7 @@ class SmallListTile extends StatelessWidget {
size: 18.0,
),
),
visualDensity: compact ? VisualDensity.compact : null,
visualDensity: compact ? const VisualDensity(horizontal: -2.0, vertical: -2.0) : const VisualDensity(horizontal: -1.0, vertical: -1.0),
title: Text(
title,
style: context.textTheme.displayMedium?.copyWith(
111 changes: 79 additions & 32 deletions lib/ui/widgets/settings/advanced_settings.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:io';

import 'package:flutter/material.dart';

import 'package:checkmark/checkmark.dart';
@@ -261,7 +263,6 @@ class AdvancedSettings extends StatelessWidget {
trailingText: Indexer.inst.videosSizeInStorage.value.fileSizeFormatted,
onTap: () async {
final allvideo = VideoController.inst.getCurrentVideosInCache();
allvideo.sortByReverse((e) => e.sizeInBytes);

/// First Dialog
NamidaNavigator.inst.navigateDialog(
@@ -303,8 +304,30 @@ class AdvancedSettings extends StatelessWidget {
.replaceFirst('_TOTAL_SIZE_', videos.fold(0, (previousValue, element) => previousValue + element.sizeInBytes).fileSizeFormatted);
}

_showChooseVideosToDeleteDialog(List<NamidaVideo> videoFiles) {
_showChooseVideosToDeleteDialog(List<NamidaVideo> allVideoFiles) {
final RxList<NamidaVideo> videosToDelete = <NamidaVideo>[].obs;
final videoFiles = List<NamidaVideo>.from(allVideoFiles).obs;
final isSortTypeSize = true.obs;

sortBySize() {
videoFiles.sortByReverse((e) => e.sizeInBytes);
isSortTypeSize.value = true;
}

sortByAccessTime() {
videoFiles.sortBy((e) => File(e.path).statSync().accessed);
isSortTypeSize.value = false;
}

toggleSort() {
if (isSortTypeSize.value) {
sortByAccessTime();
} else {
sortBySize();
}
}

sortBySize();
NamidaNavigator.inst.navigateDialog(
dialog: CustomBlurryDialog(
insetPadding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 32.0),
@@ -348,39 +371,63 @@ class AdvancedSettings extends StatelessWidget {
child: SizedBox(
width: Get.width,
height: Get.height * 0.65,
child: ListView.builder(
itemCount: videoFiles.length,
itemBuilder: (context, index) {
final video = videoFiles[index];
return Obx(
() => ListTile(
contentPadding: const EdgeInsets.symmetric(horizontal: 24.0),
leading: ArtworkWidget(
thumbnailSize: 70.0,
iconSize: 24.0,
width: 70,
height: 70 * 9 / 16,
path: video.pathToYTImage,
),
title: Text(video.ytID ?? ''),
subtitle: Text("${video.height}p • ${video.framerate}fps - ${video.sizeInBytes.fileSizeFormatted}"),
trailing: IgnorePointer(
child: SizedBox(
height: 18.0,
width: 18.0,
child: CheckMark(
strokeWidth: 2,
activeColor: context.theme.listTileTheme.iconColor!,
inactiveColor: context.theme.listTileTheme.iconColor!,
duration: const Duration(milliseconds: 400),
active: videosToDelete.contains(video),
),
child: Column(
children: [
const SizedBox(height: 6.0),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Obx(
() => NamidaButton(
icon: Broken.sort,
text: isSortTypeSize.value ? Language.inst.SIZE : Language.inst.OLDEST_WATCH,
onPressed: toggleSort,
),
),
onTap: () => videosToDelete.addOrRemove(video),
const SizedBox(width: 24.0)
],
),
const SizedBox(height: 6.0),
Expanded(
child: Obx(
() => ListView.builder(
padding: EdgeInsets.zero,
itemCount: videoFiles.length,
itemBuilder: (context, index) {
final video = videoFiles[index];
return Obx(
() => ListTile(
contentPadding: const EdgeInsets.symmetric(horizontal: 24.0),
leading: ArtworkWidget(
thumbnailSize: 70.0,
iconSize: 24.0,
width: 70,
height: 70 * 9 / 16,
path: video.pathToYTImage,
),
title: Text(video.ytID ?? ''),
subtitle: Text("${video.height}p • ${video.framerate}fps - ${video.sizeInBytes.fileSizeFormatted}"),
trailing: IgnorePointer(
child: SizedBox(
height: 18.0,
width: 18.0,
child: CheckMark(
strokeWidth: 2,
activeColor: context.theme.listTileTheme.iconColor!,
inactiveColor: context.theme.listTileTheme.iconColor!,
duration: const Duration(milliseconds: 400),
active: videosToDelete.contains(video),
),
),
),
onTap: () => videosToDelete.addOrRemove(video),
),
);
},
),
),
);
},
),
],
),
),
),
77 changes: 39 additions & 38 deletions lib/ui/widgets/settings/indexer_settings.dart
Original file line number Diff line number Diff line change
@@ -21,37 +21,38 @@ class IndexerSettings extends StatelessWidget {

SettingsController get stg => SettingsController.inst;

Future<void> _showRefreshPromptDialog() async {
RefreshLibraryIcon.controller.repeat();
final currentFiles = await Indexer.inst.getAudioFiles();
Future<void> _showRefreshPromptDialog(bool didModifyFolder) async {
_RefreshLibraryIcon.controller.repeat();
final currentFiles = await Indexer.inst.getAudioFiles(forceReCheckDirs: didModifyFolder);
final newPathsLength = Indexer.inst.getNewFoundPaths(currentFiles).length;
final deletedPathLength = Indexer.inst.getDeletedPaths(currentFiles).length;
if (newPathsLength == 0 && deletedPathLength == 0) {
Get.snackbar(Language.inst.NOTE, Language.inst.NO_CHANGES_FOUND);
return;
}
NamidaNavigator.inst.navigateDialog(
dialog: CustomBlurryDialog(
title: Language.inst.NOTE,
bodyText: Language.inst.PROMPT_INDEXING_REFRESH.replaceFirst('_NEW_FILES_', newPathsLength.toString()).replaceFirst(
'_DELETED_FILES_',
deletedPathLength.toString(),
} else {
NamidaNavigator.inst.navigateDialog(
dialog: CustomBlurryDialog(
title: Language.inst.NOTE,
bodyText: Language.inst.PROMPT_INDEXING_REFRESH.replaceFirst('_NEW_FILES_', newPathsLength.toString()).replaceFirst(
'_DELETED_FILES_',
deletedPathLength.toString(),
),
actions: [
const CancelButton(),
NamidaButton(
text: Language.inst.REFRESH,
onPressed: () async {
NamidaNavigator.inst.closeDialog();
await Future.delayed(const Duration(milliseconds: 300));
await Indexer.inst.refreshLibraryAndCheckForDiff(currentFiles: currentFiles);
},
),
actions: [
const CancelButton(),
NamidaButton(
text: Language.inst.REFRESH,
onPressed: () async {
NamidaNavigator.inst.closeDialog();
await Future.delayed(const Duration(milliseconds: 300));
await Indexer.inst.refreshLibraryAndCheckForDiff(currentFiles: currentFiles);
},
),
],
),
);
await RefreshLibraryIcon.controller.fling(velocity: 0.6);
RefreshLibraryIcon.controller.stop();
],
),
);
}

await _RefreshLibraryIcon.controller.fling(velocity: 0.6);
_RefreshLibraryIcon.controller.stop();
}

Widget addFolderButton(void Function(String dirPath) onSuccessChoose) {
@@ -66,7 +67,7 @@ class IndexerSettings extends StatelessWidget {
}

onSuccessChoose(path);
_showRefreshPromptDialog();
_showRefreshPromptDialog(true);
},
);
}
@@ -254,10 +255,10 @@ class IndexerSettings extends StatelessWidget {
},
),
CustomListTile(
leading: const RefreshLibraryIcon(),
leading: const _RefreshLibraryIcon(),
title: Language.inst.REFRESH_LIBRARY,
subtitle: Language.inst.REFRESH_LIBRARY_SUBTITLE,
onTap: () => _showRefreshPromptDialog(),
onTap: () => _showRefreshPromptDialog(false),
),
Obx(
() => NamidaExpansionTile(
@@ -301,7 +302,7 @@ class IndexerSettings extends StatelessWidget {
onPressed: () {
SettingsController.inst.removeFromList(directoriesToScan1: e);
NamidaNavigator.inst.closeDialog();
_showRefreshPromptDialog();
_showRefreshPromptDialog(true);
},
),
],
@@ -351,7 +352,7 @@ class IndexerSettings extends StatelessWidget {
trailing: TextButton(
onPressed: () {
SettingsController.inst.removeFromList(directoriesToExclude1: e);
_showRefreshPromptDialog();
_showRefreshPromptDialog(true);
},
child: Text(Language.inst.REMOVE.toUpperCase()),
),
@@ -524,35 +525,35 @@ class IndexerSettings extends StatelessWidget {
}
}

class RefreshLibraryIcon extends StatefulWidget {
const RefreshLibraryIcon({Key? key}) : super(key: key);
class _RefreshLibraryIcon extends StatefulWidget {
const _RefreshLibraryIcon({Key? key}) : super(key: key);
static late AnimationController controller;

@override
State<RefreshLibraryIcon> createState() => _RefreshLibraryIconState();
State<_RefreshLibraryIcon> createState() => __RefreshLibraryIconState();
}

class _RefreshLibraryIconState extends State<RefreshLibraryIcon> with TickerProviderStateMixin {
class __RefreshLibraryIconState extends State<_RefreshLibraryIcon> with TickerProviderStateMixin {
final turnsTween = Tween<double>(begin: 0.0, end: 1.0);
@override
void initState() {
super.initState();
RefreshLibraryIcon.controller = AnimationController(
_RefreshLibraryIcon.controller = AnimationController(
duration: const Duration(milliseconds: 1200),
vsync: this,
);
}

@override
void dispose() {
RefreshLibraryIcon.controller.dispose();
_RefreshLibraryIcon.controller.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return RotationTransition(
turns: turnsTween.animate(RefreshLibraryIcon.controller),
turns: turnsTween.animate(_RefreshLibraryIcon.controller),
child: const Icon(
Broken.refresh_2,
),

0 comments on commit 71a0a82

Please sign in to comment.