Skip to content

Commit

Permalink
chore: refresh library icon in indexer card
Browse files Browse the repository at this point in the history
  • Loading branch information
MSOB7YY committed Dec 12, 2023
1 parent 447469f commit 5dea8b1
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 24 deletions.
17 changes: 8 additions & 9 deletions lib/ui/widgets/circular_percentages.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:get/get.dart';
import 'package:namida/controller/json_to_history_parser.dart';
import 'package:namida/core/constants.dart';
import 'package:namida/core/enums.dart';
import 'package:namida/core/extensions.dart';
import 'package:namida/ui/widgets/custom_widgets.dart';
import 'package:namida/controller/indexer_controller.dart';

Expand All @@ -15,15 +16,13 @@ class IndexingPercentage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Obx(
() => Indexer.inst.isIndexing.value
? NamidaHero(
tag: 'indexingper',
child: NamidaCircularPercentage(
percentage: allTracksInLibrary.length / Indexer.inst.allAudioFiles.length,
size: size,
),
)
: const SizedBox(),
() => NamidaHero(
tag: 'indexingper',
child: NamidaCircularPercentage(
percentage: allTracksInLibrary.length / Indexer.inst.allAudioFiles.length,
size: size,
).animateEntrance(showWhen: Indexer.inst.isIndexing.value),
),
);
}
}
Expand Down
87 changes: 72 additions & 15 deletions lib/ui/widgets/settings/indexer_settings.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:async';

import 'package:flutter/material.dart';

import 'package:file_picker/file_picker.dart';
Expand Down Expand Up @@ -61,7 +63,7 @@ class IndexerSettings extends SettingSubpageProvider {
};

Future<void> _showRefreshPromptDialog(bool didModifyFolder) async {
_RefreshLibraryIcon.controller.repeat();
_RefreshLibraryIconController.repeat();
final currentFiles = await Indexer.inst.getAudioFiles(forceReCheckDirs: didModifyFolder);
final newPathsLength = Indexer.inst.getNewFoundPaths(currentFiles).length;
final deletedPathLength = Indexer.inst.getDeletedPaths(currentFiles).length;
Expand Down Expand Up @@ -96,8 +98,8 @@ class IndexerSettings extends SettingSubpageProvider {
);
}

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

Widget addFolderButton(void Function(String dirPath) onSuccessChoose) {
Expand Down Expand Up @@ -304,13 +306,26 @@ class IndexerSettings extends SettingSubpageProvider {

@override
Widget build(BuildContext context) {
const refreshIconKey1 = 'kurukuru';
const refreshIconKey2 = 'kururin';
return SettingsCard(
title: lang.INDEXER,
subtitle: lang.INDEXER_SUBTITLE,
icon: Broken.component,
trailing: const SizedBox(
height: 48.0,
child: IndexingPercentage(),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
NamidaIconButton(
icon: Broken.refresh_2,
tooltip: lang.REFRESH_LIBRARY,
onPressed: () => _showRefreshPromptDialog(false),
child: const _RefreshLibraryIcon(widgetKey: refreshIconKey2),
),
const SizedBox(
height: 48.0,
child: IndexingPercentage(),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
Expand Down Expand Up @@ -624,7 +639,7 @@ class IndexerSettings extends SettingSubpageProvider {
key: _IndexerSettingsKeys.refreshLibrary,
child: CustomListTile(
bgColor: getBgColor(_IndexerSettingsKeys.refreshLibrary),
leading: const _RefreshLibraryIcon(),
leading: const _RefreshLibraryIcon(widgetKey: refreshIconKey1),
title: lang.REFRESH_LIBRARY,
subtitle: lang.REFRESH_LIBRARY_SUBTITLE,
onTap: () => _showRefreshPromptDialog(false),
Expand Down Expand Up @@ -800,9 +815,54 @@ class IndexerSettings extends SettingSubpageProvider {
}
}

class _RefreshLibraryIconController {
static final _controllers = <String, AnimationController>{};

static AnimationController getController(String key) => _controllers[key]!;

static void init(String key, TickerProvider vsync) {
_controllers[key] ??= AnimationController(
duration: const Duration(milliseconds: 1200),
vsync: vsync,
);
}

static void dispose(String key) {
_controllers[key]?.dispose();
_controllers.remove(key);
}

static void repeat() {
_loopControllers((c) => c?.repeat());
}

static Future<void> fling() async {
int controllersFlinging = _controllers.length;
final completer = Completer<void>();
_loopControllers(
(c) => c?.fling(velocity: 0.6).then((value) {
controllersFlinging--;
if (controllersFlinging == 0) completer.completeIfWasnt();
}),
);
await completer.future;
}

static void stop() {
_loopControllers((c) => c?.stop());
}

static void _loopControllers(void Function(AnimationController? c) execute) {
for (final k in _controllers.keys) {
final controller = _controllers[k];
execute(controller);
}
}
}

class _RefreshLibraryIcon extends StatefulWidget {
const _RefreshLibraryIcon({Key? key}) : super(key: key);
static late AnimationController controller;
final String widgetKey;
const _RefreshLibraryIcon({required this.widgetKey});

@override
State<_RefreshLibraryIcon> createState() => _RefreshLibraryIconState();
Expand All @@ -813,22 +873,19 @@ class _RefreshLibraryIconState extends State<_RefreshLibraryIcon> with TickerPro
@override
void initState() {
super.initState();
_RefreshLibraryIcon.controller = AnimationController(
duration: const Duration(milliseconds: 1200),
vsync: this,
);
_RefreshLibraryIconController.init(widget.widgetKey, this);
}

@override
void dispose() {
_RefreshLibraryIcon.controller.dispose();
_RefreshLibraryIconController.dispose(widget.widgetKey);
super.dispose();
}

@override
Widget build(BuildContext context) {
return RotationTransition(
turns: turnsTween.animate(_RefreshLibraryIcon.controller),
turns: turnsTween.animate(_RefreshLibraryIconController.getController(widget.widgetKey)),
child: Icon(
Broken.refresh_2,
color: context.defaultIconColor(),
Expand Down

0 comments on commit 5dea8b1

Please sign in to comment.