Files
lunasea/lib/modules/nzbget/widgets/queue_fab.dart
Jagandeep Brar 5cf33b3abd [Release/TestFlight] v4.1.0+40100001 (#266)
NEW
- [Networking] Strict TLS/SSL validation is now disabled globally
- [Routing] Hold the AppBar back button to pop back to the home page of the module
- [Settings/Sonarr] Toggle to enable Sonarr v3 features
- [Sonarr] Complete rewrite of Sonarr
- [Sonarr] State is now held across module switches
- [Sonarr/Overview] View tags applied to series
- [Sonarr/Catalogue] (v3 only) Ability to set and update language profile
- [Sonarr/Catalogue] Ability to view all, only monitored, or only unmonitored series
- [Sonarr/Releases] (v3 only) Ability to interactively search for season packs
- [Sonarr/Releases] Ability to view all, only approved, or only rejected releases

TWEAKS
- [Settings] Removed all toggles for strict TLS
- [Sonarr] Many tweaks to Sonarr's design
- [Sonarr/Add] (v3 only) Tapping an already-added series will take you to the series page
- [Sonarr/Add] Automatically navigate to newly added series
- [Sonarr/Series] Toggling monitored state of series has now been moved to the edit prompt

FIXES
- [Images] Images will now load for invalid/self-signed certificates
- [Tautulli/Activity] Fix grey screen for music activity
- [TextField] Fix TextField actions (cut, copy, paste, etc.) not showing
- [Timestamps] Fix 12:xx AM being shown as 00:xx AM
- Additional small bug fixes
2020-10-13 09:43:28 -05:00

167 lines
5.7 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:lunasea/core.dart';
import 'package:tuple/tuple.dart';
import 'package:lunasea/modules/nzbget.dart';
class NZBGetQueueFAB extends StatefulWidget {
final ScrollController scrollController;
NZBGetQueueFAB({
Key key,
@required this.scrollController,
}) : super(key: key);
@override
State<StatefulWidget> createState() => _State();
}
class _State extends State<NZBGetQueueFAB> with TickerProviderStateMixin {
AnimationController _iconController;
AnimationController _hideController;
bool _visible = true;
@override
void initState() {
super.initState();
_setupIconController();
_setupHideController();
}
@override
void dispose() {
_iconController?.dispose();
_hideController?.dispose();
super.dispose();
}
void _setupIconController() {
_iconController = AnimationController(
vsync: this,
duration: Duration(milliseconds: Constants.UI_NAVIGATION_SPEED),
);
}
void _setupHideController() {
_hideController = AnimationController(
vsync: this,
duration: Duration(milliseconds: Constants.UI_NAVIGATION_SPEED),
);
_hideController.forward();
widget.scrollController.addListener(() {
switch(widget.scrollController.position.userScrollDirection) {
case ScrollDirection.forward: if(!_visible) {
_hideController.forward();
_visible = true;
} break;
case ScrollDirection.reverse: if(_visible) {
_hideController.reverse();
_visible = false;
} break;
case ScrollDirection.idle: break;
}
});
}
@override
Widget build(BuildContext context) => Selector<NZBGetState, Tuple2<bool, bool>>(
selector: (_, model) => Tuple2(model.error, model.paused),
builder: (context, data, _) {
data.item2
? _iconController.forward()
: _iconController.reverse();
return data.item1
? Container()
: ScaleTransition(
scale: _hideController,
child: InkWell(
child: LSFloatingActionButtonAnimated(
controller: _iconController,
icon: AnimatedIcons.pause_play,
onPressed: () => _toggle(context, data.item2),
),
onLongPress: () => _toggleFor(context),
borderRadius: BorderRadius.circular(28.0),
),
);
}
);
Future<void> _toggle(BuildContext context, bool paused) async {
NZBGetAPI _api = NZBGetAPI.from(Database.currentProfileObject);
paused
? _resume(context, _api)
: _pause(context, _api);
}
Future<void> _toggleFor(BuildContext context) async {
List values = await NZBGetDialogs.pauseFor(context);
if(values[0]) {
if(values[1] == -1) {
List values = await NZBGetDialogs.customPauseFor(context);
if(values[0]) await NZBGetAPI.from(Database.currentProfileObject).pauseQueueFor(values[1])
.then((_) => LSSnackBar(
context: context,
title: 'Pausing Queue',
message: 'For ${(values[1] as int).lsTime_durationString(multiplier: 60)}',
type: SNACKBAR_TYPE.success,
))
.catchError((_) => LSSnackBar(
context: context,
title: 'Failed to Pause Queue',
message: Constants.CHECK_LOGS_MESSAGE,
type: SNACKBAR_TYPE.failure,
));
} else {
await NZBGetAPI.from(Database.currentProfileObject).pauseQueueFor(values[1])
.then((_) => LSSnackBar(
context: context,
title: 'Pausing Queue',
message: 'For ${(values[1] as int).lsTime_durationString(multiplier: 60)}',
type: SNACKBAR_TYPE.success,
))
.catchError((_) => LSSnackBar(
context: context,
title: 'Failed to Pause Queue',
message: Constants.CHECK_LOGS_MESSAGE,
type: SNACKBAR_TYPE.failure,
));
}
}
}
Future<void> _pause(BuildContext context, NZBGetAPI api) async {
_iconController.forward();
await api.pauseQueue()
.then((_) {
Provider.of<NZBGetState>(context, listen: false).paused = true;
})
.catchError((_) {
_iconController.reverse();
LSSnackBar(
context: context,
title: 'Failed to Pause Queue',
message: Constants.CHECK_LOGS_MESSAGE,
type: SNACKBAR_TYPE.failure,
);
});
}
Future<void> _resume(BuildContext context, NZBGetAPI api) async {
_iconController.reverse();
return await api.resumeQueue()
.then((_) {
Provider.of<NZBGetState>(context, listen: false).paused = false;
})
.catchError((_) {
_iconController.forward();
LSSnackBar(
context: context,
title: 'Failed to Resume Queue',
message: Constants.CHECK_LOGS_MESSAGE,
type: SNACKBAR_TYPE.failure,
);
});
}
}