mirror of
https://github.com/jagandeepbrar/lunasea.git
synced 2026-08-31 12:42:34 +00:00
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
183 lines
5.8 KiB
Dart
183 lines
5.8 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:lunasea/core.dart';
|
|
import 'package:lunasea/modules/nzbget.dart';
|
|
|
|
class NZBGetQueue extends StatefulWidget {
|
|
static const ROUTE_NAME = '/nzbget/queue';
|
|
final GlobalKey<RefreshIndicatorState> refreshIndicatorKey;
|
|
|
|
NZBGetQueue({
|
|
Key key,
|
|
@required this.refreshIndicatorKey,
|
|
}) : super(key: key);
|
|
|
|
@override
|
|
State<NZBGetQueue> createState() => _State();
|
|
}
|
|
|
|
class _State extends State<NZBGetQueue> with TickerProviderStateMixin, AutomaticKeepAliveClientMixin {
|
|
final _scaffoldKey = GlobalKey<ScaffoldState>();
|
|
final _scrollController = ScrollController();
|
|
Timer _timer;
|
|
Future _future;
|
|
List<NZBGetQueueData> _queue = [];
|
|
|
|
@override
|
|
bool get wantKeepAlive => true;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_refresh();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
super.build(context);
|
|
return Scaffold(
|
|
key: _scaffoldKey,
|
|
body: _body,
|
|
floatingActionButton: NZBGetQueueFAB(scrollController: _scrollController),
|
|
);
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_timer?.cancel();
|
|
super.dispose();
|
|
}
|
|
|
|
void _createTimer() => _timer = Timer(Duration(seconds: 2), () => _fetchWithoutMessage());
|
|
|
|
Future<void> _refresh() async => setState(() {
|
|
_future = _fetch();
|
|
});
|
|
|
|
Future<void> _fetchWithoutMessage() async {
|
|
_fetch().then((_) => { if(mounted) setState(() {}) })
|
|
.catchError((_) => _queue = null);
|
|
}
|
|
|
|
Future _fetch() async {
|
|
NZBGetAPI _api = NZBGetAPI.from(Database.currentProfileObject);
|
|
return _fetchStatus(_api)
|
|
.then((_) => _fetchQueue(_api))
|
|
.then((_) {
|
|
try {
|
|
if(_timer == null || !_timer.isActive) _createTimer();
|
|
_setError(false);
|
|
return true;
|
|
} catch (error) {
|
|
return Future.error(error);
|
|
}
|
|
})
|
|
.catchError((error) {
|
|
_queue = null;
|
|
_setError(true);
|
|
return Future.error(error);
|
|
});
|
|
}
|
|
|
|
Future<void> _fetchQueue(NZBGetAPI api) async {
|
|
final _model = Provider.of<NZBGetState>(context, listen: false);
|
|
return await api.getQueue(_model.speed, 100)
|
|
.then((data) => _queue = data)
|
|
.catchError((error) => Future.error(error));
|
|
}
|
|
|
|
Future<void> _fetchStatus(NZBGetAPI api) async {
|
|
return await api.getStatus()
|
|
.then((data) {
|
|
if(mounted) {
|
|
final _model = Provider.of<NZBGetState>(context, listen: false);
|
|
_model.paused = data.paused;
|
|
_model.speed = data.speed;
|
|
_model.currentSpeed = data.currentSpeed;
|
|
_model.queueSizeLeft = data.remainingString;
|
|
_model.queueTimeLeft = data.timeLeft;
|
|
_model.speedLimit = data.speedlimitString;
|
|
}
|
|
})
|
|
.catchError((error) => Future.error(error));
|
|
}
|
|
|
|
void _setError(bool error) {
|
|
final _model = Provider.of<NZBGetState>(context, listen: false);
|
|
_model.error = error;
|
|
}
|
|
|
|
Widget get _body => LSRefreshIndicator(
|
|
refreshKey: widget.refreshIndicatorKey,
|
|
onRefresh: () => _fetchWithoutMessage(),
|
|
child: FutureBuilder(
|
|
future: _future,
|
|
builder: (context, snapshot) {
|
|
if(
|
|
snapshot.connectionState == ConnectionState.done
|
|
&& (snapshot.hasError || snapshot.data == null)
|
|
) return LSErrorMessage(onTapHandler: () => _refresh());
|
|
return _list;
|
|
},
|
|
),
|
|
);
|
|
|
|
Widget get _list => _queue == null
|
|
? LSErrorMessage(onTapHandler: () => _refresh())
|
|
: _queue.length == 0
|
|
? LSGenericMessage(
|
|
text: 'Empty Queue',
|
|
showButton: true,
|
|
buttonText: 'Refresh',
|
|
onTapHandler: () => _fetchWithoutMessage(),
|
|
)
|
|
: _reorderableList;
|
|
|
|
Widget get _reorderableList => Scrollbar(
|
|
child: LSReorderableListView(
|
|
scrollController: _scrollController,
|
|
onReorder: (oIndex, nIndex) async {
|
|
if (oIndex > _queue.length) oIndex = _queue.length;
|
|
if (oIndex < nIndex) nIndex--;
|
|
NZBGetQueueData data = _queue[oIndex];
|
|
if(mounted) setState(() {
|
|
_queue.remove(data);
|
|
_queue.insert(nIndex, data);
|
|
});
|
|
await NZBGetAPI.from(Database.currentProfileObject).moveQueue(data.id, (nIndex - oIndex))
|
|
.then((_) => LSSnackBar(
|
|
context: context,
|
|
title: 'Moved Job in Queue',
|
|
message: data.name,
|
|
type: SNACKBAR_TYPE.success,
|
|
))
|
|
.catchError((_) => LSSnackBar(
|
|
context: context,
|
|
title: 'Failed to Move Job',
|
|
message: Constants.CHECK_LOGS_MESSAGE,
|
|
type: SNACKBAR_TYPE.failure,
|
|
));
|
|
},
|
|
children: List.generate(
|
|
_queue.length,
|
|
(index) => NZBGetQueueTile(
|
|
key: Key(_queue[index].id.toString()),
|
|
data: _queue[index],
|
|
snackbar: _snackBar,
|
|
queueContext: context,
|
|
refresh: () => _fetchWithoutMessage(),
|
|
),
|
|
),
|
|
padding: EdgeInsets.only(top: 8.0),
|
|
),
|
|
);
|
|
|
|
void _snackBar(String title, String message, SNACKBAR_TYPE type) => LSSnackBar(
|
|
context: context,
|
|
title: title,
|
|
message: message,
|
|
type: type,
|
|
);
|
|
}
|