mirror of
https://github.com/jagandeepbrar/lunasea.git
synced 2026-08-30 20:24:25 +00:00
* [iOS/Build] Add GoogleUtilities pod to prevent archive errors * (chore) version bump * [Git] Initialize blackbox * [Git] Initialize blackbox * [Git/Blackbox] Add me@jagandeepbrar.io as admin * registered in blackbox: ios/ExportOptions.plist * registered in blackbox: ios/GoogleService-Info.plist * registered in blackbox: android/key.properties * registered in blackbox: android/app/google-services.json * Re-encrypted keys * registered in blackbox: android/key.jks * Updated key.properties, re-encrypted * [Android/Keystore] Update same key.properties * [Tautulli/Activity] Incorrectly localized "Transcodes" string * [Radarr, UI] Implemented quick manual import, Implemented new design of ExpandableTile across UI (#378) * Use local path for radarr package * [Radarr/Manual Import] Browse filesystem, trigger quick import * [UI/Buttons] Normalize the height of all buttons * Update packages * [ListView] Exposed itemExtent property * [Lidarr/Releases] Move from LSExpandable to LunaExpandableListTile implementation * [Tautulli/Logs] Use the new expandable table card styling * [SABnzbd/History] Use the newer expandable table card styling * [NZBGet/History] Use the newer expandable table card styling * [UI/Button] Reduce size of the loader and icon to closer match text size * [Sonarr/Releases] Use the newer expandable table card styling * [Sonarr/Episodes] Use the newer expandable table card styling * [UI/Table] Safe-guard title and body text, show emdash when receiving null data * [Radarr/Details] Show monitor status and properly update the overview table on edit or monitor status changes * Updated changelog * [Sonarr/Queue & Episodes] Cleaned up implementation of expandable tile * Translated using Weblate (Norwegian Bokmål) Currently translated at 100.0% (14 of 14 strings) Translation: LunaSea/LunaSea Translate-URL: https://hosted.weblate.org/projects/lunasea/lunasea/nb_NO/ * Translated using Weblate (Swedish) Currently translated at 100.0% (14 of 14 strings) Translation: LunaSea/LunaSea Translate-URL: https://hosted.weblate.org/projects/lunasea/lunasea/sv/ * Translated using Weblate (German) Currently translated at 100.0% (68 of 68 strings) Translation: LunaSea/Tautulli Translate-URL: https://hosted.weblate.org/projects/lunasea/tautulli/de/ * Translated using Weblate (Norwegian Bokmål) Currently translated at 80.8% (55 of 68 strings) Translation: LunaSea/Tautulli Translate-URL: https://hosted.weblate.org/projects/lunasea/tautulli/nb_NO/ * Translated using Weblate (Swedish) Currently translated at 100.0% (68 of 68 strings) Translation: LunaSea/Tautulli Translate-URL: https://hosted.weblate.org/projects/lunasea/tautulli/sv/ * Translated using Weblate (Russian) Currently translated at 57.3% (39 of 68 strings) Translation: LunaSea/Tautulli Translate-URL: https://hosted.weblate.org/projects/lunasea/tautulli/ru/ * (chore) Build localizations * [Tautulli/Webhooks] Implement webhook data handlers for all Tautulli webhooks (#380) * [Tautulli/Webhooks] Handle transcode decision change and watched event types * [Radarr/Sonarr] Safe-guard webhooks by pushing the home route on invalid received data blocks * [Tautulli/Webhooks] Implemented all webhooks * Translated using Weblate (French) Currently translated at 100.0% (78 of 78 strings) Translation: LunaSea/Radarr Translate-URL: https://hosted.weblate.org/projects/lunasea/radarr/fr/ * Translated using Weblate (German) Currently translated at 100.0% (78 of 78 strings) Translation: LunaSea/Radarr Translate-URL: https://hosted.weblate.org/projects/lunasea/radarr/de/ * Translated using Weblate (Russian) Currently translated at 92.8% (13 of 14 strings) Translation: LunaSea/LunaSea Translate-URL: https://hosted.weblate.org/projects/lunasea/lunasea/ru/ * [Release] (chore): Dirty v5.0.0+50000013 (#382) * [Radarr/Manual Import] Add search bar for host system path, add stub manual import page * [Radarr/Manual Import] Change path bar text to "File Browser..." * [Radarr/Manual Import] Pass "/" if textController text is null * [Radarr/Import] Stub details state * [Database] Correctly register LunaIndexerIcon hive adapter * [Radarr/Import] Filter directories when typing path, Fetch manual import results with stub cards * [UI/Bottom Bar] Abstract bottom action bar, use on add movie page * [UI/Navigation Bar] Add option to attach stickied top actions to navigation bar * [Radarr/Edit] Use stickied bottom action bar for buttons * [Radarr/Details] use sticky navigation actions for interactive and automatic search * [Dialogs] CheckboxTiles were padded too aggressively in the X-axis * [Sentry] Remove remaining references to Sentry * (chore) Build localizations * (chore) Update changelog * Preparing to shift GitHub repository structure Co-authored-by: Allan Nordhøy <epost@anotheragency.no> Co-authored-by: Patrik Hauguth <patrik.hauguth@gmail.com> Co-authored-by: cpt-kuesel <jln.sltr@pm.me> Co-authored-by: Artem <KovalevArtem.ru@gmail.com> Co-authored-by: Antoine C <contact+weblate@antoinecardon.fr>
460 lines
18 KiB
Dart
460 lines
18 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:lunasea/core.dart';
|
|
import 'package:lunasea/modules/radarr.dart';
|
|
|
|
class RadarrDialogs {
|
|
Future<Tuple2<bool, RadarrGlobalSettingsType>> globalSettings(BuildContext context) async {
|
|
bool _flag = false;
|
|
RadarrGlobalSettingsType _value;
|
|
|
|
void _setValues(bool flag, RadarrGlobalSettingsType value) {
|
|
_flag = flag;
|
|
_value = value;
|
|
Navigator.of(context, rootNavigator: true).pop();
|
|
}
|
|
|
|
await LSDialog.dialog(
|
|
context: context,
|
|
title: 'lunasea.Settings'.tr(),
|
|
content: List.generate(
|
|
RadarrGlobalSettingsType.values.length,
|
|
(index) => LSDialog.tile(
|
|
text: RadarrGlobalSettingsType.values[index].name,
|
|
icon: RadarrGlobalSettingsType.values[index].icon,
|
|
iconColor: LunaColours.list(index),
|
|
onTap: () => _setValues(true, RadarrGlobalSettingsType.values[index]),
|
|
),
|
|
),
|
|
contentPadding: LSDialog.listDialogContentPadding(),
|
|
);
|
|
return Tuple2(_flag, _value);
|
|
}
|
|
|
|
Future<Tuple2<bool, RadarrMovieSettingsType>> movieSettings(BuildContext context, RadarrMovie movie) async {
|
|
bool _flag = false;
|
|
RadarrMovieSettingsType _value;
|
|
|
|
void _setValues(bool flag, RadarrMovieSettingsType value) {
|
|
_flag = flag;
|
|
_value = value;
|
|
Navigator.of(context, rootNavigator: true).pop();
|
|
}
|
|
|
|
await LSDialog.dialog(
|
|
context: context,
|
|
title: movie.title,
|
|
content: List.generate(
|
|
RadarrMovieSettingsType.values.length,
|
|
(index) => LSDialog.tile(
|
|
text: RadarrMovieSettingsType.values[index].name(movie),
|
|
icon: RadarrMovieSettingsType.values[index].icon(movie),
|
|
iconColor: LunaColours.list(index),
|
|
onTap: () => _setValues(true, RadarrMovieSettingsType.values[index]),
|
|
),
|
|
),
|
|
contentPadding: LSDialog.listDialogContentPadding(),
|
|
);
|
|
return Tuple2(_flag, _value);
|
|
}
|
|
|
|
Future<Tuple2<bool, int>> setDefaultPage(BuildContext context, {
|
|
@required List<String> titles,
|
|
@required List<IconData> icons,
|
|
}) async {
|
|
bool _flag = false;
|
|
int _index = 0;
|
|
|
|
void _setValues(bool flag, int index) {
|
|
_flag = flag;
|
|
_index = index;
|
|
Navigator.of(context, rootNavigator: true).pop();
|
|
}
|
|
|
|
await LSDialog.dialog(
|
|
context: context,
|
|
title: 'Page',
|
|
content: List.generate(
|
|
titles.length,
|
|
(index) => LSDialog.tile(
|
|
text: titles[index],
|
|
icon: icons[index],
|
|
iconColor: LunaColours.list(index),
|
|
onTap: () => _setValues(true, index),
|
|
),
|
|
),
|
|
contentPadding: LSDialog.listDialogContentPadding(),
|
|
);
|
|
|
|
return Tuple2(_flag, _index);
|
|
}
|
|
|
|
Future<Tuple2<bool, int>> setDefaultSortingOrFiltering(BuildContext context, {
|
|
@required List<String> titles,
|
|
}) async {
|
|
bool _flag = false;
|
|
int _index = 0;
|
|
|
|
void _setValues(bool flag, int index) {
|
|
_flag = flag;
|
|
_index = index;
|
|
Navigator.of(context, rootNavigator: true).pop();
|
|
}
|
|
|
|
await LSDialog.dialog(
|
|
context: context,
|
|
title: 'Sorting & Filtering',
|
|
content: List.generate(
|
|
titles.length,
|
|
(index) => LSDialog.tile(
|
|
text: titles[index],
|
|
icon: Icons.sort,
|
|
iconColor: LunaColours.list(index),
|
|
onTap: () => _setValues(true, index),
|
|
),
|
|
),
|
|
contentPadding: LSDialog.listDialogContentPadding(),
|
|
);
|
|
|
|
return Tuple2(_flag, _index);
|
|
}
|
|
|
|
Future<Tuple2<bool, String>> addNewTag(BuildContext context) async {
|
|
bool _flag = false;
|
|
final _formKey = GlobalKey<FormState>();
|
|
final _textController = TextEditingController();
|
|
|
|
void _setValues(bool flag) {
|
|
if(_formKey.currentState.validate()) {
|
|
_flag = flag;
|
|
Navigator.of(context, rootNavigator: true).pop();
|
|
}
|
|
}
|
|
|
|
await LSDialog.dialog(
|
|
context: context,
|
|
title: 'Add Tag',
|
|
buttons: [
|
|
LSDialog.button(
|
|
text: 'Add',
|
|
onPressed: () => _setValues(true),
|
|
),
|
|
],
|
|
content: [
|
|
Form(
|
|
key: _formKey,
|
|
child: LSDialog.textFormInput(
|
|
controller: _textController,
|
|
title: 'Tag Label',
|
|
onSubmitted: (_) => _setValues(true),
|
|
validator: (value) {
|
|
if(value == null || value.isEmpty) return 'Label cannot be empty';
|
|
return null;
|
|
},
|
|
),
|
|
),
|
|
],
|
|
contentPadding: LSDialog.inputDialogContentPadding(),
|
|
);
|
|
return Tuple2(_flag, _textController.text);
|
|
}
|
|
|
|
Future<bool> deleteTag(BuildContext context) async {
|
|
bool _flag = false;
|
|
|
|
void _setValues(bool flag) {
|
|
_flag = flag;
|
|
Navigator.of(context, rootNavigator: true).pop();
|
|
}
|
|
|
|
await LSDialog.dialog(
|
|
context: context,
|
|
title: 'Delete Tag',
|
|
buttons: [
|
|
LSDialog.button(
|
|
text: 'Delete',
|
|
textColor: LunaColours.red,
|
|
onPressed: () => _setValues(true),
|
|
),
|
|
],
|
|
content: [
|
|
LSDialog.textContent(text: 'Are you sure you want to delete this tag?'),
|
|
],
|
|
contentPadding: LSDialog.textDialogContentPadding(),
|
|
);
|
|
return _flag;
|
|
}
|
|
|
|
Future<bool> searchAllMissingMovies(BuildContext context) async {
|
|
bool _flag = false;
|
|
|
|
void _setValues(bool flag) {
|
|
_flag = flag;
|
|
Navigator.of(context, rootNavigator: true).pop();
|
|
}
|
|
|
|
await LSDialog.dialog(
|
|
context: context,
|
|
title: 'Missing Movies',
|
|
buttons: [
|
|
LSDialog.button(
|
|
text: 'Search',
|
|
onPressed: () => _setValues(true),
|
|
),
|
|
],
|
|
content: [
|
|
LSDialog.textContent(text: 'Are you sure you want to search for all missing movies?'),
|
|
],
|
|
contentPadding: LSDialog.textDialogContentPadding(),
|
|
);
|
|
return _flag;
|
|
}
|
|
|
|
Future<bool> deleteMovieFile(BuildContext context) async {
|
|
bool _flag = false;
|
|
|
|
void _setValues(bool flag) {
|
|
_flag = flag;
|
|
Navigator.of(context, rootNavigator: true).pop();
|
|
}
|
|
|
|
await LSDialog.dialog(
|
|
context: context,
|
|
title: 'Delete File',
|
|
buttons: [
|
|
LSDialog.button(
|
|
text: 'Delete',
|
|
textColor: LunaColours.red,
|
|
onPressed: () => _setValues(true),
|
|
),
|
|
],
|
|
content: [
|
|
LSDialog.textContent(text: 'Are you sure you want to delete this movie file?'),
|
|
],
|
|
contentPadding: LSDialog.textDialogContentPadding(),
|
|
);
|
|
return _flag;
|
|
}
|
|
|
|
Future<Tuple2<bool, RadarrAvailability>> editMinimumAvailability(BuildContext context) async {
|
|
bool _flag = false;
|
|
RadarrAvailability availability;
|
|
|
|
void _setValues(bool flag, RadarrAvailability value) {
|
|
_flag = flag;
|
|
availability = value;
|
|
Navigator.of(context, rootNavigator: true).pop();
|
|
}
|
|
|
|
await LSDialog.dialog(
|
|
context: context,
|
|
title: 'radarr.MinimumAvailability'.tr(),
|
|
content: List.generate(
|
|
RadarrAvailability.values.length,
|
|
(index) => LSDialog.tile(
|
|
text: RadarrAvailability.values[index].readable,
|
|
icon: Icons.folder,
|
|
iconColor: LunaColours.list(index),
|
|
onTap: () => _setValues(true, RadarrAvailability.values[index]),
|
|
),
|
|
),
|
|
contentPadding: LSDialog.listDialogContentPadding(),
|
|
);
|
|
return Tuple2(_flag, availability);
|
|
}
|
|
|
|
Future<Tuple2<bool, RadarrQualityProfile>> editQualityProfile(BuildContext context, List<RadarrQualityProfile> profiles) async {
|
|
bool _flag = false;
|
|
RadarrQualityProfile profile;
|
|
|
|
void _setValues(bool flag, RadarrQualityProfile value) {
|
|
_flag = flag;
|
|
profile = value;
|
|
Navigator.of(context, rootNavigator: true).pop();
|
|
}
|
|
|
|
await LSDialog.dialog(
|
|
context: context,
|
|
title: 'radarr.QualityProfile'.tr(),
|
|
content: List.generate(
|
|
profiles.length,
|
|
(index) => LSDialog.tile(
|
|
text: profiles[index].name,
|
|
icon: Icons.portrait,
|
|
iconColor: LunaColours.list(index),
|
|
onTap: () => _setValues(true, profiles[index]),
|
|
),
|
|
),
|
|
contentPadding: LSDialog.listDialogContentPadding(),
|
|
);
|
|
return Tuple2(_flag, profile);
|
|
}
|
|
|
|
Future<void> setEditTags(BuildContext context) async {
|
|
await showDialog(
|
|
context: context,
|
|
builder: (dContext) => ChangeNotifierProvider.value(
|
|
value: context.read<RadarrMoviesEditState>(),
|
|
builder: (context, _) => AlertDialog(
|
|
actions: <Widget>[
|
|
RadarrTagsAppBarActionAddTag(asDialogButton: true),
|
|
LSDialog.button(
|
|
text: 'Close',
|
|
onPressed: () => Navigator.of(context, rootNavigator: true).pop(),
|
|
),
|
|
],
|
|
title: LSDialog.title(text: 'Tags'),
|
|
content: Selector<RadarrState, Future<List<RadarrTag>>>(
|
|
selector: (_, state) => state.tags,
|
|
builder: (context, future, _) => FutureBuilder(
|
|
future: future,
|
|
builder: (context, AsyncSnapshot<List<RadarrTag>> snapshot) {
|
|
if((snapshot.data?.length ?? 0) == 0) return LSDialog.content(
|
|
children: [
|
|
LSDialog.textContent(text: 'No Tags Found'),
|
|
],
|
|
);
|
|
return LSDialog.content(
|
|
children: List.generate(
|
|
snapshot.data.length,
|
|
(index) => LSDialog.checkbox(
|
|
title: snapshot.data[index].label,
|
|
value: context.watch<RadarrMoviesEditState>().tags.where((tag) => tag.id == snapshot.data[index].id).length != 0,
|
|
onChanged: (selected) {
|
|
List<RadarrTag> _tags = context.read<RadarrMoviesEditState>().tags;
|
|
selected ? _tags.add(snapshot.data[index]) : _tags.removeWhere((tag) => tag.id == snapshot.data[index].id);
|
|
context.read<RadarrMoviesEditState>().tags = _tags;
|
|
},
|
|
),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
contentPadding: LSDialog.listDialogContentPadding(),
|
|
shape: LunaUI.shapeBorder,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<void> setAddTags(BuildContext context) async {
|
|
await showDialog(
|
|
context: context,
|
|
builder: (dContext) => ChangeNotifierProvider.value(
|
|
value: context.read<RadarrAddMovieDetailsState>(),
|
|
builder: (context, _) => AlertDialog(
|
|
actions: <Widget>[
|
|
RadarrTagsAppBarActionAddTag(asDialogButton: true),
|
|
LSDialog.button(
|
|
text: 'Close',
|
|
onPressed: () => Navigator.of(context, rootNavigator: true).pop(),
|
|
),
|
|
|
|
],
|
|
title: LSDialog.title(text: 'Tags'),
|
|
content: Selector<RadarrState, Future<List<RadarrTag>>>(
|
|
selector: (_, state) => state.tags,
|
|
builder: (context, future, _) => FutureBuilder(
|
|
future: future,
|
|
builder: (context, AsyncSnapshot<List<RadarrTag>> snapshot) {
|
|
if((snapshot.data?.length ?? 0) == 0) return LSDialog.content(
|
|
children: [
|
|
LSDialog.textContent(text: 'No Tags Found'),
|
|
],
|
|
);
|
|
return LSDialog.content(
|
|
children: List.generate(
|
|
snapshot.data.length,
|
|
(index) => LSDialog.checkbox(
|
|
title: snapshot.data[index].label,
|
|
value: context.watch<RadarrAddMovieDetailsState>().tags.where((tag) => tag.id == snapshot.data[index].id).length != 0,
|
|
onChanged: (selected) {
|
|
List<RadarrTag> _tags = context.read<RadarrAddMovieDetailsState>().tags;
|
|
selected ? _tags.add(snapshot.data[index]) : _tags.removeWhere((tag) => tag.id == snapshot.data[index].id);
|
|
context.read<RadarrAddMovieDetailsState>().tags = _tags;
|
|
},
|
|
),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
contentPadding: LSDialog.listDialogContentPadding(),
|
|
shape: LunaUI.shapeBorder,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<Tuple2<bool, RadarrRootFolder>> editRootFolder(BuildContext context, List<RadarrRootFolder> folders) async {
|
|
bool _flag = false;
|
|
RadarrRootFolder _folder;
|
|
|
|
void _setValues(bool flag, RadarrRootFolder value) {
|
|
_flag = flag;
|
|
_folder = value;
|
|
Navigator.of(context, rootNavigator: true).pop();
|
|
}
|
|
|
|
await LSDialog.dialog(
|
|
context: context,
|
|
title: 'radarr.RootFolder'.tr(),
|
|
content: List.generate(
|
|
folders.length,
|
|
(index) => LSDialog.tile(
|
|
text: folders[index].path,
|
|
subtitle: LSDialog.richText(
|
|
children: [
|
|
LSDialog.bolded(text: folders[index].freeSpace.lunaBytesToString())
|
|
],
|
|
),
|
|
icon: Icons.folder,
|
|
iconColor: LunaColours.list(index),
|
|
onTap: () => _setValues(true, folders[index]),
|
|
),
|
|
),
|
|
contentPadding: LSDialog.listDialogContentPadding(),
|
|
);
|
|
return Tuple2(_flag, _folder);
|
|
}
|
|
|
|
Future<bool> removeMovie(BuildContext context) async {
|
|
bool _flag = false;
|
|
|
|
void _setValues(bool flag) {
|
|
_flag = flag;
|
|
Navigator.of(context, rootNavigator: true).pop();
|
|
}
|
|
|
|
await LSDialog.dialog(
|
|
context: context,
|
|
title: 'Remove Movie',
|
|
buttons: [
|
|
LSDialog.button(
|
|
text: 'Remove',
|
|
textColor: LunaColours.red,
|
|
onPressed: () => _setValues(true),
|
|
),
|
|
],
|
|
content: [
|
|
RadarrDatabaseValue.REMOVE_MOVIE_IMPORT_LIST.listen(
|
|
builder: (context, value, _) => LSDialog.checkbox(
|
|
title: 'Add to Exclusion List',
|
|
value: RadarrDatabaseValue.REMOVE_MOVIE_IMPORT_LIST.data,
|
|
onChanged: (value) => RadarrDatabaseValue.REMOVE_MOVIE_IMPORT_LIST.put(value),
|
|
),
|
|
),
|
|
RadarrDatabaseValue.REMOVE_MOVIE_DELETE_FILES.listen(
|
|
builder: (context, value, _) => LSDialog.checkbox(
|
|
title: 'Delete Files',
|
|
value: RadarrDatabaseValue.REMOVE_MOVIE_DELETE_FILES.data,
|
|
onChanged: (value) => RadarrDatabaseValue.REMOVE_MOVIE_DELETE_FILES.put(value),
|
|
),
|
|
),
|
|
],
|
|
contentPadding: LSDialog.listDialogContentPadding(),
|
|
);
|
|
return _flag;
|
|
}
|
|
}
|