feat(settings): replace all strings with localizable strings

This commit is contained in:
Jagandeep Brar
2023-03-30 04:06:13 -04:00
parent 0f4ac9a893
commit 5ce12795e7
42 changed files with 384 additions and 566 deletions

View File

@@ -57,6 +57,8 @@
"lunasea.DownloadClient": "Download Client",
"lunasea.Edge": "Edge",
"lunasea.Error": "Error",
"lunasea.EverySecond": "Every Second",
"lunasea.EverySeconds": "Every {} Seconds",
"lunasea.ExternalModules": "External Modules",
"lunasea.Features": "Features",
"lunasea.Fixes": "Fixes",
@@ -70,6 +72,7 @@
"lunasea.IncorrectEncryptionKey": "Incorrect encryption key",
"lunasea.Internal": "Internal",
"lunasea.InvalidFileTypeSelected": "Invalid File Type Selected",
"lunasea.Items": "{} Items",
"lunasea.JustNow": "Just Now",
"lunasea.Minutes": "{} Minutes",
"lunasea.MinutesAgo": "{} Minutes Ago",
@@ -85,6 +88,7 @@
"lunasea.OneDayAgo": "1 Day Ago",
"lunasea.OneHour": "1 Hour",
"lunasea.OneHourAgo": "1 Hour Ago",
"lunasea.OneItem": "1 Item",
"lunasea.OneMinute": "1 Minute",
"lunasea.OneMinuteAgo": "1 Minute Ago",
"lunasea.OneMonth": "1 Month",
@@ -113,6 +117,8 @@
"lunasea.Settings": "Settings",
"lunasea.Stable": "Stable",
"lunasea.StartingView": "Starting View",
"lunasea.ThankYou": "Thank You",
"lunasea.ThankYouMessage": "Thank you for supporting the open-source community!",
"lunasea.Today": "Today",
"lunasea.TransactionFailure": "Transaction Failure",
"lunasea.TryAgain": "Try Again",
@@ -181,6 +187,8 @@
"radarr.DigitalRelease": "Digital Release",
"radarr.DirectoryNotFound": "Directory Not Found",
"radarr.Discover": "Discover",
"radarr.DiscoverSuggestions": "Discover Suggestions",
"radarr.DiscoverSuggestionsDescription": "Add Suggested Releases in Discover",
"radarr.Disks": "Disks",
"radarr.DownloadFailed": "Download Failed",
"radarr.DownloadIgnored": "Download Ignored",
@@ -215,6 +223,7 @@
"radarr.MoveFilesDescription": "Would you like to move the files?",
"radarr.MoveFull": "Move Files",
"radarr.Movie": "Movie",
"radarr.MovieDetails": "Movie Details",
"radarr.Movies": "Movies",
"radarr.MovieFileDeleted": "Movie File Deleted",
"radarr.MovieFileRenamed": "Movie File Renamed",
@@ -237,6 +246,7 @@
"radarr.QualityProfile": "Quality Profile",
"radarr.Queue": "Queue",
"radarr.QueueDescription": "View Active & Queued Content",
"radarr.QueueSize": "Queue Size",
"radarr.Quick": "Quick",
"radarr.RefreshMovie": "Refresh Movie",
"radarr.Rejected": "Rejected",
@@ -306,25 +316,39 @@
"sabnzbd.ShutdownSABnzbd": "Shutdown SABnzbd",
"sabnzbd.StandbyPC": "Standby PC",
"sabnzbd.Stop": "Stop",
"search.AddIndexer": "Add Indexer",
"search.Age": "Age",
"search.AllSubcategories": "All Subcategories",
"search.Alphabetical": "Alphabetical",
"search.Category": "Category",
"search.Categories": "Categories",
"search.Comments": "Comments",
"search.DeleteIndexer": "Delete Indexer",
"search.Download": "Download",
"search.Downloading": "Downloading…",
"search.DownloadingNZBToDevice": "Downloading NZB to your device",
"search.DownloadToDevice": "Download to Device",
"search.EditIndexer": "Edit Indexer",
"search.FailedToAddIndexer": "Failed to Add indexer",
"search.FailedToDownloadNZB": "Failed to Download NZB",
"search.FailedToSend": "Failed to Send",
"search.HideAdultCategories": "Hide Adult Categories",
"search.HideAdultCategoriesDescription": "Hide Adult Content",
"search.IndexerAPIHost": "Indexer API Host",
"search.IndexerAPIKey": "Indexer API Key",
"search.IndexerAdded": "Indexer Added",
"search.IndexerDeleted": "Indexer Deleted",
"search.IndexerNotFound": "Indexer Not Found",
"search.NoCategoriesFound": "No Categories Found",
"search.NoIndexersFound": "No Indexers Found",
"search.NoResultsFound": "No Results Found",
"search.NoSubcategoriesFound": "No Subcategories Found",
"search.Results": "Results",
"search.Search": "Search",
"search.SentNZBData": "Sent NZB Data",
"search.SentTo": "Sent to {}",
"search.ShowLinks": "Show Links",
"search.ShowLinksDescription": "Show Download and Comments Links",
"search.Size": "Size",
"search.Subcategories": "Subcategories",
"settings.Account": "Account",
@@ -343,6 +367,8 @@
"settings.AddProfileDescription": "Add a New Profile",
"settings.AddedProfile": "Added Profile",
"settings.AllFieldsAreRequired": "All fields are required",
"settings.AllLogs": "All Logs",
"settings.AllLogsDescription": "View Logs of All Types",
"settings.AmoledTheme": "AMOLED Theme",
"settings.AmoledThemeBorders": "AMOLED Theme Borders",
"settings.AmoledThemeBordersDescription": "Add Subtle Borders Across the UI",
@@ -381,9 +407,12 @@
"settings.BuildChannels": "Build Channels",
"settings.BuildChannelsDescription": "Learn About Additional Build Channels",
"settings.CalendarSettings": "Calendar Settings",
"settings.CalendarSettingsDescription": "Customize the Unified Calendar",
"settings.ChangedProfile": "Changed Profile",
"settings.Channel": "Channel",
"settings.Class": "Class",
"settings.CleanSlate": "Clean Slate",
"settings.Clear": "Clear",
"settings.ClearConfiguration": "Clear Configuration",
"settings.ClearConfigurationHint1": "Are you sure you want to clear your configuration?",
"settings.ClearConfigurationHint2": "You will be starting from a clean slate, please ensure you backup your current configuration first!",
@@ -404,6 +433,9 @@
"settings.ConnectionDetails": "Connection Details",
"settings.ConnectionDetailsDescription": "Connection Details for {}",
"settings.ConnectionTestFailed": "Connection Test Failed",
"settings.CopiedURLFor": "Copied URL for {}",
"settings.CopiedDeviceURL": "Copied your device-based URL to the clipboard",
"settings.CopiedUserURL": "Copied your user-based URL to the clipboard",
"settings.CurrentPassword": "Current Password",
"settings.Custom": "Custom…",
"settings.CustomHeader": "Custom Header",
@@ -444,6 +476,7 @@
"settings.DeleteModuleSuccess": "Module Deleted",
"settings.DeleteProfile": "Delete Profile",
"settings.DeleteProfileDescription": "Delete an Existing Profile",
"settings.Device": "Device",
"settings.DiscordDescription": "Request Features & Get Support",
"settings.DismissBanners": "Dismiss Banners",
"settings.DismissBannersHint1": "Are you sure you want to dismiss all tooltip banners?",
@@ -467,6 +500,10 @@
"settings.EnableModule": "Enable {}",
"settings.EnabledProfile": "Enabled Profile",
"settings.EncryptionKey": "Encryption Key",
"settings.Exception": "Exception",
"settings.Export": "Export",
"settings.ExportedLogs": "Exported Logs",
"settings.ExportedLogsMessage": "Logs have been successfully exported",
"settings.FailedToClearImageCache": "Failed to Clear Image Cache",
"settings.FailedToClearImageCacheDescription": "The image cache could not be cleared",
"settings.FailedToDeleteAccount": "Failed to Delete Account",
@@ -477,6 +514,8 @@
"settings.FutureDays": "Future Days",
"settings.General": "General",
"settings.GeneralDescription": "Customize LunaSea",
"settings.GettingStarted": "Getting Started",
"settings.GettingStartedDescription": "Information & Setup Instructions",
"settings.GitHubDescription": "View the Source Code",
"settings.HeaderAdded": "Header Added",
"settings.HeaderDeleted": "Header Deleted",
@@ -507,7 +546,10 @@
"settings.Localization": "Localization",
"settings.LocalizationDescription": "Customize to your Locale",
"settings.Logs": "Logs",
"settings.LogsCleared": "Logs Cleared",
"settings.LogsClearedDescription": "All recorded logs have been cleared",
"settings.LogsDescription": "View, Export, and Clear Logs",
"settings.Method": "Method",
"settings.MACAddress": "MAC Address",
"settings.MACAddressHint1": "This is the MAC address of the machine that you want to wake up",
"settings.MACAddressHint2": "MAC addresses contain six two-digit hexadecimal nibbles (an octet)",
@@ -520,12 +562,16 @@
"settings.Network": "Network",
"settings.NetworkDescription": "Customize Network Features",
"settings.NewPassword": "New Password",
"settings.NotAuthorized": "Not Authorized",
"settings.NotAuthorizedMessage": "LunaSea is not authorized to show notifications. Please go to your device's settings to enable notifications.",
"settings.NotAvailable": "Not Available",
"settings.Notifications": "Notifications",
"settings.NotificationsDescription": "Set up Webhooks for Push Notifications",
"settings.NoAdditionalProfilesAdded": "No additional profiles have been added",
"settings.NoBackupsFound": "No Backups Found",
"settings.NoExternalModulesFound": "No External Modules Found",
"settings.NoHeadersAdded": "No Headers Added",
"settings.NoLogsFound": "No Logs Found",
"settings.NoProfilesFound": "No Profiles Found",
"settings.OpenDrawerOnBackAction": "Open Drawer on Back Action",
"settings.OpenDrawerOnBackActionDescription": "Open the drawer instead of closing LunaSea",
@@ -596,6 +642,7 @@
"settings.UpToDate": "Up To Date",
"settings.Use24HourTime": "Use 24 Hour Time",
"settings.Use24HourTimeDescription": "Show Timestamps in 24 Hour Style",
"settings.User": "User",
"settings.Username": "Username",
"settings.UsernameValidation": "Username Required",
"settings.Version": "Version",
@@ -738,6 +785,7 @@
"sonarr.Queue": "Queue",
"sonarr.Queued": "Queued",
"sonarr.QueueDescription": "View Active & Queued Content",
"sonarr.QueueSize": "Queue Size",
"sonarr.Reason": "Reason",
"sonarr.RefreshSeries": "Refresh Series",
"sonarr.Rejected": "Rejected",
@@ -817,6 +865,7 @@
"sonarr.WordScore": "Word Score",
"tautulli.Activity": "Activity",
"tautulli.ActivityDetails": "Activity Details",
"tautulli.ActivityRefreshRate": "Activity Refresh Rate",
"tautulli.Audio": "Audio",
"tautulli.BackingUpConfiguration": "Backing Up Configuration…",
"tautulli.BackingUpConfigurationDescription": "Backing up your configuration in the background",
@@ -831,6 +880,7 @@
"tautulli.Converting": "Converting",
"tautulli.Container": "Container",
"tautulli.Copy": "Copy",
"tautulli.DefaultTerminationMessage": "Default Termination Message",
"tautulli.DeleteCache": "Delete Cache",
"tautulli.DeleteImageCache": "Delete Image Cache",
"tautulli.DeleteTemporarySessions": "Delete Temporary Sessions",
@@ -850,9 +900,12 @@
"tautulli.Duration": "Duration",
"tautulli.Episode": "Episode {}",
"tautulli.ETA": "ETA",
"tautulli.Graphs": "Graphs",
"tautulli.History": "History",
"tautulli.Library": "Library",
"tautulli.LibraryDetails": "Library Details",
"tautulli.Location": "Location",
"tautulli.MediaDetails": "Media Details",
"tautulli.Metadata": "Metadata",
"tautulli.More": "More",
"tautulli.None": "None",
@@ -867,6 +920,8 @@
"tautulli.SessionsOne": "1 Session",
"tautulli.SessionsMany": "{} Sessions",
"tautulli.Speed": "Speed: {}x",
"tautulli.Statistics": "Statistics",
"tautulli.StatisticsItemCount": "Statistics Item Count",
"tautulli.Stream": "Stream",
"tautulli.Subtitle": "Subtitle",
"tautulli.Terminate": "Terminate",
@@ -882,6 +937,7 @@
"tautulli.Transcodes": "Transcodes",
"tautulli.User": "User",
"tautulli.Users": "Users",
"tautulli.UserDetails": "User Details",
"tautulli.Video": "Video",
"tautulli.ViewWebGUI": "View Web GUI",
"tautulli.Year": "Year",

View File

@@ -436,6 +436,23 @@ extension LunaModuleWebhookExtension on LunaModule {
}
}
String? get webhookDocs {
switch (this) {
case LunaModule.LIDARR:
return 'https://docs.lunasea.app/lunasea/notifications/lidarr';
case LunaModule.RADARR:
return 'https://docs.lunasea.app/lunasea/notifications/radarr';
case LunaModule.SONARR:
return 'https://docs.lunasea.app/lunasea/notifications/sonarr';
case LunaModule.OVERSEERR:
return 'https://docs.lunasea.app/lunasea/notifications/overseerr';
case LunaModule.TAUTULLI:
return 'https://docs.lunasea.app/lunasea/notifications/tautulli';
default:
return null;
}
}
Future<void> handleWebhook(Map<String, dynamic> data) async {
switch (this) {
case LunaModule.LIDARR:

View File

@@ -125,9 +125,9 @@ class _State extends State<SettingsHeaderRoute> with LunaScrollControllerMixin {
Future<void> _resetState() async {
switch (widget.module) {
case LunaModule.DASHBOARD:
throw Exception('Dashboard does not have a headers page');
throw Exception('Dashboard does not have a global state');
case LunaModule.EXTERNAL_MODULES:
throw Exception('External modules do not have a headers page');
throw Exception('External modules do not have a global state');
case LunaModule.LIDARR:
return;
case LunaModule.RADARR:
@@ -139,11 +139,11 @@ class _State extends State<SettingsHeaderRoute> with LunaScrollControllerMixin {
case LunaModule.NZBGET:
return;
case LunaModule.SEARCH:
throw Exception('Search does not have a headers page');
throw Exception('Search does not have a global state');
case LunaModule.SETTINGS:
throw Exception('Settings does not have a headers page');
throw Exception('Settings does not have a global state');
case LunaModule.WAKE_ON_LAN:
throw Exception('Wake on LAN does not have a headers page');
throw Exception('Wake on LAN does not have a global state');
case LunaModule.TAUTULLI:
return context.read<TautulliState>().reset();
case LunaModule.OVERSEERR:

View File

@@ -45,9 +45,7 @@ class HeaderUtility {
await _genericHeader(context, headers, indexer);
break;
default:
LunaLogger().warning(
'Unknown case: ${result.item2}',
);
LunaLogger().warning('Unknown case: ${result.item2}');
}
}

View File

@@ -52,8 +52,8 @@ class _State extends State<ConfigurationDashboardRoute>
Widget _calendarSettingsPage() {
return LunaBlock(
title: 'Calendar Settings',
body: const [TextSpan(text: 'Customize the Unified Calendar')],
title: 'settings.CalendarSettings'.tr(),
body: [TextSpan(text: 'settings.CalendarSettingsDescription'.tr())],
trailing: const LunaIconButton.arrow(),
onTap: SettingsRoutes.CONFIGURATION_DASHBOARD_CALENDAR.go,
);

View File

@@ -46,7 +46,7 @@ class _State extends State<ConfigurationOverseerrRoute>
Widget _enabledToggle() {
return LunaBox.profiles.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'Enable ${LunaModule.OVERSEERR.title}',
title: 'settings.EnableModule'.tr(args: [LunaModule.OVERSEERR.title]),
trailing: LunaSwitch(
value: LunaProfile.current.overseerrEnabled,
onChanged: (value) {

View File

@@ -66,7 +66,7 @@ class _State extends State<ConfigurationRadarrDefaultPagesRoute>
const _db = RadarrDatabase.NAVIGATION_INDEX_MOVIE_DETAILS;
return _db.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'Movie Details',
title: 'radarr.MovieDetails'.tr(),
body: [
TextSpan(text: RadarrMovieDetailsNavigationBar.titles[_db.read()]),
],
@@ -89,7 +89,7 @@ class _State extends State<ConfigurationRadarrDefaultPagesRoute>
const _db = RadarrDatabase.NAVIGATION_INDEX_ADD_MOVIE;
return _db.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'Add Movie',
title: 'radarr.AddMovie'.tr(),
body: [TextSpan(text: RadarrAddMovieNavigationBar.titles[_db.read()])],
trailing:
LunaIconButton(icon: RadarrAddMovieNavigationBar.icons[_db.read()]),
@@ -109,7 +109,7 @@ class _State extends State<ConfigurationRadarrDefaultPagesRoute>
const _db = RadarrDatabase.NAVIGATION_INDEX_SYSTEM_STATUS;
return _db.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'System Status',
title: 'radarr.SystemStatus'.tr(),
body: [
TextSpan(text: RadarrSystemStatusNavigationBar.titles[_db.read()]),
],

View File

@@ -27,7 +27,7 @@ class _State extends State<ConfigurationRadarrRoute>
Widget _appBar() {
return LunaAppBar(
title: 'Radarr',
title: LunaModule.RADARR.title,
scrollControllers: [scrollController],
);
}
@@ -51,7 +51,7 @@ class _State extends State<ConfigurationRadarrRoute>
Widget _enabledToggle() {
return LunaBox.profiles.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'Enable ${LunaModule.RADARR.title}',
title: 'settings.EnableModule'.tr(args: [LunaModule.RADARR.title]),
trailing: LunaSwitch(
value: LunaProfile.current.radarrEnabled,
onChanged: (value) {
@@ -66,8 +66,14 @@ class _State extends State<ConfigurationRadarrRoute>
Widget _connectionDetailsPage() {
return LunaBlock(
title: 'Connection Details',
body: const [TextSpan(text: 'Connection Details for Radarr')],
title: 'settings.ConnectionDetails'.tr(),
body: [
TextSpan(
text: 'settings.ConnectionDetailsDescription'.tr(
args: [LunaModule.RADARR.title],
),
),
],
trailing: const LunaIconButton.arrow(),
onTap: SettingsRoutes.CONFIGURATION_RADARR_CONNECTION_DETAILS.go,
);
@@ -84,8 +90,8 @@ class _State extends State<ConfigurationRadarrRoute>
Widget _defaultPagesPage() {
return LunaBlock(
title: 'Default Pages',
body: const [TextSpan(text: 'Set Default Landing Pages')],
title: 'settings.DefaultPages'.tr(),
body: [TextSpan(text: 'settings.DefaultPagesDescription'.tr())],
trailing: const LunaIconButton.arrow(),
onTap: SettingsRoutes.CONFIGURATION_RADARR_DEFAULT_PAGES.go,
);
@@ -95,8 +101,8 @@ class _State extends State<ConfigurationRadarrRoute>
const _db = RadarrDatabase.ADD_DISCOVER_USE_SUGGESTIONS;
return _db.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'Discover Suggestions',
body: const [TextSpan(text: 'Add Suggested Releases in Discover')],
title: 'radarr.DiscoverSuggestions'.tr(),
body: [TextSpan(text: 'radarr.DiscoverSuggestionsDescription'.tr())],
trailing: LunaSwitch(
value: _db.read(),
onChanged: (value) => _db.update(value),
@@ -109,9 +115,13 @@ class _State extends State<ConfigurationRadarrRoute>
const _db = RadarrDatabase.QUEUE_PAGE_SIZE;
return _db.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'Queue Size',
title: 'radarr.QueueSize'.tr(),
body: [
TextSpan(text: _db.read() == 1 ? '1 Item' : '${_db.read()} Items')
TextSpan(
text: _db.read() == 1
? 'lunasea.OneItem'.tr()
: 'lunasea.Items'.tr(args: [_db.read().toString()]),
),
],
trailing: const LunaIconButton(icon: Icons.queue_play_next_rounded),
onTap: () async {

View File

@@ -29,7 +29,7 @@ class _State extends State<ConfigurationSABnzbdConnectionDetailsRoute>
Widget _appBar() {
return LunaAppBar(
title: 'Connection Details',
title: 'settings.ConnectionDetails'.tr(),
scrollControllers: [scrollController],
);
}
@@ -104,34 +104,37 @@ class _State extends State<ConfigurationSABnzbdConnectionDetailsRoute>
Widget _testConnection() {
return LunaButton.text(
text: 'Test Connection',
text: 'settings.TestConnection'.tr(),
icon: Icons.wifi_tethering_rounded,
onTap: () async {
LunaProfile _profile = LunaProfile.current;
if (_profile.sabnzbdHost.isEmpty) {
showLunaErrorSnackBar(
title: 'Host Required',
message: 'Host is required to connect to SABnzbd',
title: 'settings.HostRequired'.tr(),
message: 'settings.HostRequiredMessage'
.tr(args: [LunaModule.SABNZBD.title]),
);
return;
}
if (_profile.sabnzbdKey.isEmpty) {
showLunaErrorSnackBar(
title: 'API Key Required',
message: 'API key is required to connect to SABnzbd',
title: 'settings.ApiKeyRequired'.tr(),
message: 'settings.ApiKeyRequiredMessage'
.tr(args: [LunaModule.SABNZBD.title]),
);
return;
}
SABnzbdAPI.from(LunaProfile.current)
.testConnection()
.then((_) => showLunaSuccessSnackBar(
title: 'Connected Successfully',
message: 'SABnzbd is ready to use with LunaSea',
title: 'settings.ConnectedSuccessfully'.tr(),
message: 'settings.ConnectedSuccessfullyMessage'
.tr(args: [LunaModule.SABNZBD.title]),
))
.catchError((error, trace) {
LunaLogger().error('Connection Test Failed', error, trace);
showLunaErrorSnackBar(
title: 'Connection Test Failed',
title: 'settings.ConnectionTestFailed'.tr(),
error: error,
);
});

View File

@@ -27,7 +27,7 @@ class _State extends State<ConfigurationSABnzbdRoute>
PreferredSizeWidget _appBar() {
return LunaAppBar(
title: 'SABnzbd',
title: LunaModule.SABNZBD.title,
scrollControllers: [scrollController],
);
}
@@ -49,7 +49,7 @@ class _State extends State<ConfigurationSABnzbdRoute>
Widget _enabledToggle() {
return LunaBox.profiles.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'Enable ${LunaModule.SABNZBD.title}',
title: 'settings.EnableModule'.tr(args: [LunaModule.SABNZBD.title]),
trailing: LunaSwitch(
value: LunaProfile.current.sabnzbdEnabled,
onChanged: (value) {

View File

@@ -29,7 +29,7 @@ class _State extends State<ConfigurationSearchAddIndexerRoute>
PreferredSizeWidget _appBar() {
return LunaAppBar(
title: 'Add Indexer',
title: 'search.AddIndexer'.tr(),
scrollControllers: [scrollController],
);
}
@@ -38,20 +38,20 @@ class _State extends State<ConfigurationSearchAddIndexerRoute>
return LunaBottomActionBar(
actions: [
LunaButton.text(
text: 'Add Indexer',
text: 'search.AddIndexer'.tr(),
icon: Icons.add_rounded,
onTap: () async {
if (_indexer.displayName.isEmpty ||
_indexer.host.isEmpty ||
_indexer.apiKey.isEmpty) {
showLunaErrorSnackBar(
title: 'Failed to Add Indexer',
message: 'All fields are required',
title: 'search.FailedToAddIndexer'.tr(),
message: 'settings.AllFieldsAreRequired'.tr(),
);
} else {
LunaBox.indexers.create(_indexer);
showLunaSuccessSnackBar(
title: 'Indexer Added',
title: 'search.IndexerAdded'.tr(),
message: _indexer.displayName,
);
Navigator.of(context).pop();
@@ -77,13 +77,13 @@ class _State extends State<ConfigurationSearchAddIndexerRoute>
Widget _displayName() {
String _name = _indexer.displayName;
return LunaBlock(
title: 'Display Name',
title: 'settings.DisplayName'.tr(),
body: [TextSpan(text: _name.isEmpty ? 'lunasea.NotSet'.tr() : _name)],
trailing: const LunaIconButton.arrow(),
onTap: () async {
Tuple2<bool, String> values = await LunaDialogs().editText(
context,
'Display Name',
'settings.DisplayName'.tr(),
prefill: _name,
);
if (values.item1 && mounted) {
@@ -96,13 +96,13 @@ class _State extends State<ConfigurationSearchAddIndexerRoute>
Widget _apiURL() {
String _host = _indexer.host;
return LunaBlock(
title: 'Indexer API Host',
title: 'search.IndexerAPIHost'.tr(),
body: [TextSpan(text: _host.isEmpty ? 'lunasea.NotSet'.tr() : _host)],
trailing: const LunaIconButton.arrow(),
onTap: () async {
Tuple2<bool, String> values = await LunaDialogs().editText(
context,
'Indexer API Host',
'search.IndexerAPIHost'.tr(),
prefill: _host,
);
if (values.item1 && mounted) {
@@ -115,13 +115,13 @@ class _State extends State<ConfigurationSearchAddIndexerRoute>
Widget _apiKey() {
String _key = _indexer.apiKey;
return LunaBlock(
title: 'Indexer API Key',
title: 'search.IndexerAPIKey'.tr(),
body: [TextSpan(text: _key.isEmpty ? 'lunasea.NotSet'.tr() : _key)],
trailing: const LunaIconButton.arrow(),
onTap: () async {
Tuple2<bool, String> values = await LunaDialogs().editText(
context,
'Indexer API Key',
'search.IndexerAPIKey'.tr(),
prefill: _key,
);
if (values.item1 && mounted) {

View File

@@ -24,8 +24,8 @@ class _State extends State<ConfigurationSearchAddIndexerHeadersRoute>
Widget build(BuildContext context) {
if (widget.indexer == null) {
return InvalidRoutePage(
title: 'Custom Headers',
message: 'Indexer Not Found',
title: 'settings.CustomHeaders'.tr(),
message: 'search.IndexerNotFound'.tr(),
);
}
@@ -39,7 +39,7 @@ class _State extends State<ConfigurationSearchAddIndexerHeadersRoute>
PreferredSizeWidget _appBar() {
return LunaAppBar(
title: 'Custom Headers',
title: 'settings.CustomHeaders'.tr(),
scrollControllers: [scrollController],
);
}
@@ -48,7 +48,7 @@ class _State extends State<ConfigurationSearchAddIndexerHeadersRoute>
return LunaBottomActionBar(
actions: [
LunaButton.text(
text: 'Add Header',
text: 'settings.AddHeader'.tr(),
icon: Icons.add_rounded,
onTap: () async {
await HeaderUtility()
@@ -65,7 +65,7 @@ class _State extends State<ConfigurationSearchAddIndexerHeadersRoute>
controller: scrollController,
children: [
if (widget.indexer!.headers.isEmpty)
LunaMessage.inList(text: 'No Headers Added'),
LunaMessage.inList(text: 'settings.NoHeadersAdded'.tr()),
..._list(),
],
);

View File

@@ -24,23 +24,24 @@ class _State extends State<ConfigurationSearchEditIndexerRoute>
@override
Widget build(BuildContext context) {
if (widget.id < 0)
if (widget.id < 0 || !LunaBox.indexers.contains(widget.id)) {
return InvalidRoutePage(
title: 'Edit Indexer', message: 'Indexer Not Found');
if (!LunaBox.indexers.contains(widget.id))
return InvalidRoutePage(
title: 'Edit Indexer', message: 'Indexer Not Found');
title: 'search.EditIndexer'.tr(),
message: 'search.IndexerNotFound'.tr(),
);
}
return LunaScaffold(
scaffoldKey: _scaffoldKey,
appBar: _appBar() as PreferredSizeWidget?,
appBar: _appBar(),
body: _body(),
bottomNavigationBar: _bottomActionBar(),
);
}
Widget _appBar() {
PreferredSizeWidget _appBar() {
return LunaAppBar(
title: 'Edit Indexer',
title: 'search.EditIndexer'.tr(),
scrollControllers: [scrollController],
);
}
@@ -49,14 +50,16 @@ class _State extends State<ConfigurationSearchEditIndexerRoute>
return LunaBottomActionBar(
actions: [
LunaButton.text(
text: 'Delete Indexer',
text: 'search.DeleteIndexer'.tr(),
icon: Icons.delete_rounded,
color: LunaColours.red,
onTap: () async {
bool result = await SettingsDialogs().deleteIndexer(context);
if (result) {
showLunaSuccessSnackBar(
title: 'Indexer Deleted', message: _indexer!.displayName);
title: 'search.IndexerDeleted'.tr(),
message: _indexer!.displayName,
);
_indexer!.delete();
Navigator.of(context).pop();
}
@@ -86,56 +89,60 @@ class _State extends State<ConfigurationSearchEditIndexerRoute>
}
Widget _displayName() {
String _name = _indexer!.displayName;
return LunaBlock(
title: 'Display Name',
body: [
TextSpan(
text: _indexer?.displayName.isEmpty ?? true
? 'Not Set'
: _indexer!.displayName,
),
],
title: 'settings.DisplayName'.tr(),
body: [TextSpan(text: _name.isEmpty ? 'lunasea.NotSet'.tr() : _name)],
trailing: const LunaIconButton.arrow(),
onTap: () async {
Tuple2<bool, String> values = await LunaDialogs()
.editText(context, 'Display Name', prefill: _indexer!.displayName);
if (values.item1) _indexer!.displayName = values.item2;
Tuple2<bool, String> values = await LunaDialogs().editText(
context,
'settings.DisplayName'.tr(),
prefill: _indexer!.displayName,
);
if (values.item1) {
_indexer!.displayName = values.item2;
}
_indexer!.save();
},
);
}
Widget _apiURL() {
String _host = _indexer!.host;
return LunaBlock(
title: 'Indexer API Host',
body: [
TextSpan(
text: _indexer?.host.isEmpty ?? true ? 'Not Set' : _indexer!.host,
),
],
title: 'search.IndexerAPIHost'.tr(),
body: [TextSpan(text: _host.isEmpty ? 'lunasea.NotSet'.tr() : _host)],
trailing: const LunaIconButton.arrow(),
onTap: () async {
Tuple2<bool, String> values = await LunaDialogs()
.editText(context, 'Indexer API Host', prefill: _indexer!.host);
if (values.item1) _indexer!.host = values.item2;
Tuple2<bool, String> values = await LunaDialogs().editText(
context,
'search.IndexerAPIHost'.tr(),
prefill: _host,
);
if (values.item1 && mounted) {
_indexer!.host = values.item2;
}
_indexer!.save();
},
);
}
Widget _apiKey() {
String _key = _indexer!.apiKey;
return LunaBlock(
title: 'Indexer API Key',
body: [
TextSpan(
text: _indexer?.apiKey.isEmpty ?? true ? 'Not Set' : _indexer!.apiKey,
),
],
title: 'search.IndexerAPIKey'.tr(),
body: [TextSpan(text: _key.isEmpty ? 'lunasea.NotSet'.tr() : _key)],
trailing: const LunaIconButton.arrow(),
onTap: () async {
Tuple2<bool, String> values = await LunaDialogs()
.editText(context, 'Indexer API Key', prefill: _indexer!.apiKey);
if (values.item1) _indexer!.apiKey = values.item2;
Tuple2<bool, String> values = await LunaDialogs().editText(
context,
'search.IndexerAPIKey'.tr(),
prefill: _key,
);
if (values.item1) {
_indexer!.apiKey = values.item2;
}
_indexer!.save();
},
);

View File

@@ -25,8 +25,8 @@ class _State extends State<ConfigurationSearchEditIndexerHeadersRoute>
Widget build(BuildContext context) {
if (widget.id < 0 || !LunaBox.indexers.contains(widget.id)) {
return InvalidRoutePage(
title: 'Custom Headers',
message: 'Indexer Not Found',
title: 'settings.CustomHeaders'.tr(),
message: 'search.IndexerNotFound'.tr(),
);
}
@@ -40,7 +40,7 @@ class _State extends State<ConfigurationSearchEditIndexerHeadersRoute>
Widget _appBar() {
return LunaAppBar(
title: 'Custom Headers',
title: 'settings.CustomHeaders'.tr(),
scrollControllers: [scrollController],
);
}
@@ -49,7 +49,7 @@ class _State extends State<ConfigurationSearchEditIndexerHeadersRoute>
return LunaBottomActionBar(
actions: [
LunaButton.text(
text: 'Add Header',
text: 'settings.AddHeader'.tr(),
icon: Icons.add_rounded,
onTap: () async => HeaderUtility().addHeader(context,
headers: _indexer!.headers, indexer: _indexer),
@@ -68,7 +68,7 @@ class _State extends State<ConfigurationSearchEditIndexerHeadersRoute>
controller: scrollController,
children: [
if (_indexer!.headers.isEmpty)
LunaMessage.inList(text: 'No Headers Added'),
LunaMessage.inList(text: 'settings.NoHeadersAdded'.tr()),
..._list(),
],
);

View File

@@ -21,15 +21,15 @@ class _State extends State<ConfigurationSearchRoute>
Widget build(BuildContext context) {
return LunaScaffold(
scaffoldKey: _scaffoldKey,
appBar: _appBar() as PreferredSizeWidget?,
appBar: _appBar(),
body: _body(),
bottomNavigationBar: _bottomNavigationBar(),
);
}
Widget _appBar() {
PreferredSizeWidget _appBar() {
return LunaAppBar(
title: 'Search',
title: 'search.Search'.tr(),
scrollControllers: [scrollController],
);
}
@@ -38,7 +38,7 @@ class _State extends State<ConfigurationSearchRoute>
return LunaBottomActionBar(
actions: [
LunaButton.text(
text: 'Add Indexer',
text: 'search.AddIndexer'.tr(),
icon: Icons.add_rounded,
onTap: SettingsRoutes.CONFIGURATION_SEARCH_ADD_INDEXER.go,
),
@@ -61,7 +61,7 @@ class _State extends State<ConfigurationSearchRoute>
List<Widget> _indexerSection() {
if (LunaBox.indexers.isEmpty) {
return [const LunaMessage(text: 'No Indexers Found')];
return [LunaMessage(text: 'search.NoIndexersFound'.tr())];
}
return _indexers;
}
@@ -103,8 +103,8 @@ class _State extends State<ConfigurationSearchRoute>
const _db = SearchDatabase.HIDE_XXX;
return _db.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'Hide Adult Categories',
body: const [TextSpan(text: 'Hide Adult Content')],
title: 'search.HideAdultCategories'.tr(),
body: [TextSpan(text: 'search.HideAdultCategoriesDescription'.tr())],
trailing: LunaSwitch(
value: _db.read(),
onChanged: _db.update,
@@ -117,8 +117,8 @@ class _State extends State<ConfigurationSearchRoute>
const _db = SearchDatabase.SHOW_LINKS;
return _db.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'Show Links',
body: const [TextSpan(text: 'Show Download and Comments Links')],
title: 'search.ShowLinks'.tr(),
body: [TextSpan(text: 'search.ShowLinksDescription'.tr())],
trailing: LunaSwitch(
value: _db.read(),
onChanged: _db.update,

View File

@@ -29,7 +29,7 @@ class _State extends State<ConfigurationSonarrConnectionDetailsRoute>
PreferredSizeWidget _appBar() {
return LunaAppBar(
title: 'Connection Details',
title: 'settings.ConnectionDetails'.tr(),
scrollControllers: [scrollController],
);
}
@@ -110,15 +110,17 @@ class _State extends State<ConfigurationSonarrConnectionDetailsRoute>
LunaProfile _profile = LunaProfile.current;
if (_profile.sonarrHost.isEmpty) {
showLunaErrorSnackBar(
title: 'Host Required',
message: 'Host is required to connect to Sonarr',
title: 'settings.HostRequired'.tr(),
message: 'settings.HostRequiredMessage'
.tr(args: [LunaModule.SONARR.title]),
);
return;
}
if (_profile.sonarrKey.isEmpty) {
showLunaErrorSnackBar(
title: 'API Key Required',
message: 'API key is required to connect to Sonarr',
title: 'settings.ApiKeyRequired'.tr(),
message: 'settings.ApiKeyRequiredMessage'
.tr(args: [LunaModule.SONARR.title]),
);
return;
}
@@ -130,8 +132,9 @@ class _State extends State<ConfigurationSonarrConnectionDetailsRoute>
),
).system.getStatus().then((_) {
showLunaSuccessSnackBar(
title: 'Connected Successfully',
message: 'Sonarr is ready to use with LunaSea',
title: 'settings.ConnectedSuccessfully'.tr(),
message: 'settings.ConnectedSuccessfullyMessage'
.tr(args: [LunaModule.SONARR.title]),
);
}).catchError((error, trace) {
LunaLogger().error(
@@ -140,7 +143,7 @@ class _State extends State<ConfigurationSonarrConnectionDetailsRoute>
trace,
);
showLunaErrorSnackBar(
title: 'Connection Test Failed',
title: 'settings.ConnectionTestFailed'.tr(),
error: error,
);
});

View File

@@ -21,12 +21,12 @@ class _State extends State<ConfigurationSonarrDefaultOptionsRoute>
Widget build(BuildContext context) {
return LunaScaffold(
scaffoldKey: _scaffoldKey,
appBar: _appBar() as PreferredSizeWidget?,
appBar: _appBar(),
body: _body(),
);
}
Widget _appBar() {
PreferredSizeWidget _appBar() {
return LunaAppBar(
title: 'settings.DefaultOptions'.tr(),
scrollControllers: [scrollController],

View File

@@ -19,12 +19,12 @@ class _State extends State<ConfigurationSonarrDefaultPagesRoute>
Widget build(BuildContext context) {
return LunaScaffold(
scaffoldKey: _scaffoldKey,
appBar: _appBar() as PreferredSizeWidget?,
appBar: _appBar(),
body: _body(),
);
}
Widget _appBar() {
PreferredSizeWidget _appBar() {
return LunaAppBar(
title: 'settings.DefaultPages'.tr(),
scrollControllers: [scrollController],

View File

@@ -20,14 +20,14 @@ class _State extends State<ConfigurationSonarrRoute>
Widget build(BuildContext context) {
return LunaScaffold(
scaffoldKey: _scaffoldKey,
appBar: _appBar() as PreferredSizeWidget?,
appBar: _appBar(),
body: _body(),
);
}
Widget _appBar() {
PreferredSizeWidget _appBar() {
return LunaAppBar(
title: 'Sonarr',
title: LunaModule.SONARR.title,
scrollControllers: [scrollController],
);
}
@@ -50,7 +50,7 @@ class _State extends State<ConfigurationSonarrRoute>
Widget _enabledToggle() {
return LunaBox.profiles.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'Enable ${LunaModule.SONARR.title}',
title: 'settings.EnableModule'.tr(args: [LunaModule.SONARR.title]),
trailing: LunaSwitch(
value: LunaProfile.current.sonarrEnabled,
onChanged: (value) {
@@ -102,9 +102,13 @@ class _State extends State<ConfigurationSonarrRoute>
const _db = SonarrDatabase.QUEUE_PAGE_SIZE;
return _db.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'Queue Size',
title: 'sonarr.QueueSize'.tr(),
body: [
TextSpan(text: _db.read() == 1 ? '1 Item' : '${_db.read()} Items')
TextSpan(
text: _db.read() == 1
? 'lunasea.OneItem'.tr()
: 'lunasea.Items'.tr(args: [_db.read().toString()]),
),
],
trailing: const LunaIconButton(icon: Icons.queue_play_next_rounded),
onTap: () async {

View File

@@ -21,15 +21,15 @@ class _State extends State<ConfigurationTautulliConnectionDetailsRoute>
Widget build(BuildContext context) {
return LunaScaffold(
scaffoldKey: _scaffoldKey,
appBar: _appBar() as PreferredSizeWidget?,
appBar: _appBar(),
body: _body(),
bottomNavigationBar: _bottomActionBar(),
);
}
Widget _appBar() {
PreferredSizeWidget _appBar() {
return LunaAppBar(
title: 'Connection Details',
title: 'settings.ConnectionDetails'.tr(),
scrollControllers: [scrollController],
);
}
@@ -110,15 +110,17 @@ class _State extends State<ConfigurationTautulliConnectionDetailsRoute>
LunaProfile _profile = LunaProfile.current;
if (_profile.tautulliHost.isEmpty) {
showLunaErrorSnackBar(
title: 'Host Required',
message: 'Host is required to connect to Tautulli',
title: 'settings.HostRequired'.tr(),
message: 'settings.HostRequiredMessage'
.tr(args: [LunaModule.TAUTULLI.title]),
);
return;
}
if (_profile.tautulliKey.isEmpty) {
showLunaErrorSnackBar(
title: 'API Key Required',
message: 'API key is required to connect to Tautulli',
title: 'settings.ApiKeyRequired'.tr(),
message: 'settings.ApiKeyRequiredMessage'
.tr(args: [LunaModule.TAUTULLI.title]),
);
return;
}
@@ -129,13 +131,14 @@ class _State extends State<ConfigurationTautulliConnectionDetailsRoute>
.miscellaneous
.arnold()
.then((_) => showLunaSuccessSnackBar(
title: 'Connected Successfully',
message: 'Tautulli is ready to use with LunaSea',
title: 'settings.ConnectedSuccessfully'.tr(),
message: 'settings.ConnectedSuccessfullyMessage'
.tr(args: [LunaModule.TAUTULLI.title]),
))
.catchError((error, trace) {
LunaLogger().error('Connection Test Failed', error, trace);
showLunaErrorSnackBar(
title: 'Connection Test Failed',
title: 'settings.ConnectionTestFailed'.tr(),
error: error,
);
});

View File

@@ -26,7 +26,7 @@ class _State extends State<ConfigurationTautulliDefaultPagesRoute>
Widget _appBar() {
return LunaAppBar(
title: 'Default Pages',
title: 'settings.DefaultPages'.tr(),
scrollControllers: [scrollController],
);
}
@@ -67,7 +67,7 @@ class _State extends State<ConfigurationTautulliDefaultPagesRoute>
const _db = TautulliDatabase.NAVIGATION_INDEX_GRAPHS;
return _db.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'Graphs',
title: 'tautulli.Graphs'.tr(),
body: [TextSpan(text: TautulliGraphsNavigationBar.titles[_db.read()])],
trailing:
LunaIconButton(icon: TautulliGraphsNavigationBar.icons[_db.read()]),
@@ -87,7 +87,7 @@ class _State extends State<ConfigurationTautulliDefaultPagesRoute>
const _db = TautulliDatabase.NAVIGATION_INDEX_LIBRARIES_DETAILS;
return _db.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'Library Details',
title: 'tautulli.LibraryDetails'.tr(),
body: [
TextSpan(
text: TautulliLibrariesDetailsNavigationBar.titles[_db.read()])
@@ -110,7 +110,7 @@ class _State extends State<ConfigurationTautulliDefaultPagesRoute>
const _db = TautulliDatabase.NAVIGATION_INDEX_MEDIA_DETAILS;
return _db.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'Media Details',
title: 'tautulli.MediaDetails'.tr(),
body: [
TextSpan(text: TautulliMediaDetailsNavigationBar.titles[_db.read()]),
],
@@ -132,7 +132,7 @@ class _State extends State<ConfigurationTautulliDefaultPagesRoute>
const _db = TautulliDatabase.NAVIGATION_INDEX_USER_DETAILS;
return _db.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'User Details',
title: 'tautulli.UserDetails'.tr(),
body: [
TextSpan(text: TautulliUserDetailsNavigationBar.titles[_db.read()]),
],

View File

@@ -20,14 +20,14 @@ class _State extends State<ConfigurationTautulliRoute>
Widget build(BuildContext context) {
return LunaScaffold(
scaffoldKey: _scaffoldKey,
appBar: _appBar() as PreferredSizeWidget?,
appBar: _appBar(),
body: _body(),
);
}
Widget _appBar() {
PreferredSizeWidget _appBar() {
return LunaAppBar(
title: 'Tautulli',
title: LunaModule.TAUTULLI.title,
scrollControllers: [scrollController],
);
}
@@ -51,7 +51,7 @@ class _State extends State<ConfigurationTautulliRoute>
Widget _enabledToggle() {
return LunaBox.profiles.listenableBuilder(
builder: (context, _) => LunaBlock(
title: 'Enable ${LunaModule.TAUTULLI.title}',
title: 'settings.EnableModule'.tr(args: [LunaModule.TAUTULLI.title]),
trailing: LunaSwitch(
value: LunaProfile.current.tautulliEnabled,
onChanged: (value) {
@@ -66,9 +66,13 @@ class _State extends State<ConfigurationTautulliRoute>
Widget _connectionDetailsPage() {
return LunaBlock(
title: 'Connection Details',
body: const [
TextSpan(text: 'Connection Details for Tautulli'),
title: 'settings.ConnectionDetails'.tr(),
body: [
TextSpan(
text: 'settings.ConnectionDetailsDescription'.tr(
args: [LunaModule.TAUTULLI.title],
),
),
],
trailing: const LunaIconButton.arrow(),
onTap: SettingsRoutes.CONFIGURATION_TAUTULLI_CONNECTION_DETAILS.go,
@@ -77,8 +81,8 @@ class _State extends State<ConfigurationTautulliRoute>
Widget _defaultPagesPage() {
return LunaBlock(
title: 'Default Pages',
body: const [TextSpan(text: 'Set Default Landing Pages')],
title: 'settings.DefaultPages'.tr(),
body: [TextSpan(text: 'settings.DefaultPagesDescription'.tr())],
trailing: const LunaIconButton.arrow(),
onTap: SettingsRoutes.CONFIGURATION_TAUTULLI_DEFAULT_PAGES.go,
);
@@ -90,8 +94,10 @@ class _State extends State<ConfigurationTautulliRoute>
builder: (context, _) {
String message = _db.read();
return LunaBlock(
title: 'Default Termination Message',
body: [TextSpan(text: message.isEmpty ? 'Not Set' : message)],
title: 'tautulli.DefaultTerminationMessage'.tr(),
body: [
TextSpan(text: message.isEmpty ? 'lunasea.NotSet'.tr() : message),
],
trailing: const LunaIconButton(icon: Icons.videocam_off_rounded),
onTap: () async {
Tuple2<bool, String> result =
@@ -106,11 +112,11 @@ class _State extends State<ConfigurationTautulliRoute>
Widget _activityRefreshRate() {
const _db = TautulliDatabase.REFRESH_RATE;
return _db.listenableBuilder(builder: (context, _) {
String? refreshRate;
if (_db.read() == 1) refreshRate = 'Every Second';
if (_db.read() != 1) refreshRate = 'Every ${_db.read()} Seconds';
String refreshRate = _db.read() == 1
? 'lunasea.EverySecond'.tr()
: 'lunasea.EverySeconds'.tr(args: [_db.read().toString()]);
return LunaBlock(
title: 'Activity Refresh Rate',
title: 'tautulli.ActivityRefreshRate'.tr(),
body: [TextSpan(text: refreshRate)],
trailing: const LunaIconButton(icon: LunaIcons.REFRESH),
onTap: () async {
@@ -125,11 +131,11 @@ class _State extends State<ConfigurationTautulliRoute>
const _db = TautulliDatabase.STATISTICS_STATS_COUNT;
return _db.listenableBuilder(
builder: (context, _) {
String? statisticsItems;
if (_db.read() == 1) statisticsItems = '1 Item';
if (_db.read() != 1) statisticsItems = '${_db.read()} Items';
String statisticsItems = _db.read() == 1
? 'lunasea.OneItem'.tr()
: 'lunasea.Items'.tr(args: [_db.read().toString()]);
return LunaBlock(
title: 'Statistics Item Count',
title: 'tautulli.StatisticsItemCount'.tr(),
body: [TextSpan(text: statisticsItems)],
trailing: const LunaIconButton(icon: Icons.format_list_numbered),
onTap: () async {

View File

@@ -27,7 +27,7 @@ class _State extends State<ConfigurationWakeOnLANRoute>
PreferredSizeWidget _appBar() {
return LunaAppBar(
scrollControllers: [scrollController],
title: 'Wake on LAN',
title: LunaModule.WAKE_ON_LAN.title,
);
}
@@ -47,7 +47,7 @@ class _State extends State<ConfigurationWakeOnLANRoute>
Widget _enabledToggle() {
return LunaBlock(
title: 'Enable Wake on LAN',
title: 'settings.EnableModule'.tr(args: [LunaModule.WAKE_ON_LAN.title]),
trailing: LunaSwitch(
value: LunaProfile.current.wakeOnLANEnabled,
onChanged: (value) {
@@ -63,7 +63,10 @@ class _State extends State<ConfigurationWakeOnLANRoute>
return LunaBlock(
title: 'settings.BroadcastAddress'.tr(),
body: [
TextSpan(text: broadcastAddress == '' ? 'Not Set' : broadcastAddress),
TextSpan(
text:
broadcastAddress == '' ? 'lunasea.NotSet'.tr() : broadcastAddress,
),
],
trailing: const LunaIconButton.arrow(),
onTap: () async {
@@ -85,7 +88,7 @@ class _State extends State<ConfigurationWakeOnLANRoute>
return LunaBlock(
title: 'settings.MACAddress'.tr(),
body: [
TextSpan(text: macAddress == '' ? 'Not Set' : macAddress),
TextSpan(text: macAddress == '' ? 'lunasea.NotSet'.tr() : macAddress),
],
trailing: const LunaIconButton.arrow(),
onTap: () async {

View File

@@ -1 +0,0 @@
export 'pages/ui.dart';

View File

@@ -1,240 +0,0 @@
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:lunasea/core.dart';
import 'package:lunasea/modules/tautulli.dart';
import 'package:lunasea/utils/links.dart';
class DebugMenuUIRoute extends StatefulWidget {
const DebugMenuUIRoute({
Key? key,
}) : super(key: key);
@override
State<DebugMenuUIRoute> createState() => _State();
}
class _State extends State<DebugMenuUIRoute>
with LunaScrollControllerMixin, TickerProviderStateMixin {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
late AnimationController _iconController;
late AnimationController _hideController;
bool _isFabVisible = true;
bool _isFabPaused = false;
@override
void initState() {
super.initState();
_setupIconController();
_setupHideController();
}
@override
void dispose() {
_iconController.dispose();
_hideController.dispose();
scrollController.removeListener(scrollControllerListener);
super.dispose();
}
void scrollControllerListener() {
if (!scrollController.hasClients) return;
switch (scrollController.position.userScrollDirection) {
case ScrollDirection.forward:
if (!_isFabVisible) {
_hideController.forward();
_isFabVisible = true;
}
break;
case ScrollDirection.reverse:
if (_isFabVisible) {
_hideController.reverse();
_isFabVisible = false;
}
break;
case ScrollDirection.idle:
break;
}
}
void _setupIconController() {
_iconController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: LunaUI.ANIMATION_SPEED),
);
}
void _setupHideController() {
_hideController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: LunaUI.ANIMATION_SPEED),
);
_hideController.forward();
scrollController.addListener(scrollControllerListener);
}
Future<void> _toggle(BuildContext context) async {
HapticFeedback.lightImpact();
_isFabPaused ? _iconController.reverse() : _iconController.forward();
setState(() => _isFabPaused = !_isFabPaused);
}
@override
Widget build(BuildContext context) {
return LunaScaffold(
scaffoldKey: _scaffoldKey,
appBar: _appBar() as PreferredSizeWidget?,
body: _body(),
floatingActionButton: _floatingActionButton(),
);
}
Widget _appBar() {
return LunaAppBar(
title: 'settings.DebugMenu'.tr(),
scrollControllers: [scrollController],
);
}
Widget _floatingActionButton() {
return ScaleTransition(
scale: _hideController,
child: InkWell(
child: LunaFloatingActionButtonAnimated(
controller: _iconController,
icon: AnimatedIcons.pause_play,
onPressed: () => _toggle(context),
),
borderRadius: BorderRadius.circular(28.0),
),
);
}
Widget _body() {
return LunaListView(
controller: scrollController,
children: [
..._lunaBlock(),
..._tableContents(),
..._graphs(),
],
);
}
List<TextSpan> _generateBody(int l) =>
List.generate(l, (i) => TextSpan(text: 'Body ${i + 1}'));
List<LunaTableContent> _generateTableContent(int l) => List.generate(l,
(i) => LunaTableContent(title: 'Title ${i + 1}', body: 'Body ${i + 1}'));
List<Widget> _tableContents() {
return [
LunaExpandableListTile(
title: 'Expandable 1',
collapsedSubtitles: _generateBody(2),
expandedTableContent: _generateTableContent(4),
collapsedTrailing: const LunaIconButton(icon: LunaIcons.ARROW_RIGHT),
),
LunaTableCard(content: _generateTableContent(4)),
];
}
List<Widget> _lunaBlock() {
return [
LunaBlock(
title: 'Title 1',
body: _generateBody(1),
bodyLeadingIcons: const [LunaIcons.DOWNLOAD],
leading: const LunaIconButton(icon: LunaIcons.ARROW_RIGHT),
trailing: const LunaIconButton(icon: LunaIcons.ARROW_RIGHT),
),
LunaBlock(
disabled: true,
title: 'Title 1',
body: _generateBody(1),
bodyLeadingIcons: const [LunaIcons.DOWNLOAD],
leading: const LunaIconButton(icon: LunaIcons.ARROW_RIGHT),
trailing: const LunaIconButton(icon: LunaIcons.ARROW_RIGHT),
),
const LunaBlock(
skeletonEnabled: true,
skeletonPoster: true,
skeletonSubtitles: 2,
),
LunaBlock(
title: 'Title 1',
body: _generateBody(2),
posterPlaceholderIcon: LunaIcons.VIDEO_CAM,
posterUrl: LunaLinkedContent.theMovieDB(
'/qLX91FhHWCVrxDVsw0g2UD5c3Zk.jpg',
LinkedContentType.IMAGE_POSTER,
),
backgroundUrl: LunaLinkedContent.theMovieDB(
'/wR3ZbCWM55qbJBcIO7rHm0MB68j.jpg',
LinkedContentType.IMAGE_BACKDROP,
),
onTap: () {},
),
];
}
List<Widget> _graphs() {
TautulliGraphData data = TautulliGraphData.fromJson(json.decode(
'{"categories":["2022-02-05","2022-02-06","2022-02-07","2022-02-08","2022-02-09","2022-02-10","2022-02-11","2022-02-12","2022-02-13","2022-02-14","2022-02-15","2022-02-16","2022-02-17","2022-02-18"],"series":[{"name":"Direct Play","data":[65,27,38,33,31,48,60,33,32,33,20,22,28,68]},{"name":"Direct Stream","data":[0,0,0,0,0,2,0,4,0,0,2,1,0,2]},{"name":"Transcode","data":[9,12,23,12,20,20,9,7,8,5,21,19,23,33]}]}',
));
return [
LunaCard(
context: context,
child: Column(
children: [
SizedBox(
height: TautulliGraphHelper.GRAPH_HEIGHT,
width: MediaQuery.of(context).size.width,
child: Padding(
child: LineChart(
LineChartData(
gridData: TautulliGraphHelper().gridData(),
titlesData: TautulliLineGraphHelper.titlesData(data),
borderData: TautulliGraphHelper().borderData(),
lineBarsData: TautulliLineGraphHelper.lineBarsData(data),
lineTouchData:
TautulliLineGraphHelper.lineTouchData(context, data),
),
),
padding: LunaUI.MARGIN_DEFAULT,
),
),
TautulliGraphHelper().createLegend(data.series!),
],
),
),
LunaCard(
context: context,
child: Column(
children: [
SizedBox(
height: TautulliGraphHelper.GRAPH_HEIGHT,
width: MediaQuery.of(context).size.width,
child: Padding(
child: BarChart(
BarChartData(
alignment: TautulliGraphHelper().chartAlignment(),
gridData: TautulliGraphHelper().gridData(),
titlesData: TautulliGraphHelper().titlesData(data),
borderData: TautulliGraphHelper().borderData(),
barGroups: TautulliBarGraphHelper.barGroups(context, data),
barTouchData:
TautulliBarGraphHelper.barTouchData(context, data),
),
),
padding: LunaUI.MARGIN_DEFAULT,
),
),
TautulliGraphHelper().createLegend(data.series!),
],
),
),
];
}
}

View File

@@ -1,78 +0,0 @@
import 'package:flutter/material.dart';
import 'package:lunasea/core.dart';
import 'package:lunasea/router/routes/settings.dart';
class DebugMenuRoute extends StatefulWidget {
const DebugMenuRoute({
Key? key,
}) : super(key: key);
@override
State<DebugMenuRoute> createState() => _State();
}
class _State extends State<DebugMenuRoute> with LunaScrollControllerMixin {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return LunaScaffold(
scaffoldKey: _scaffoldKey,
appBar: _appBar(),
body: _body(),
);
}
PreferredSizeWidget _appBar() {
return LunaAppBar(
title: 'settings.DebugMenu'.tr(),
scrollControllers: [scrollController],
);
}
Widget _body() {
return LunaListView(
controller: scrollController,
children: [
LunaBlock(
title: 'UI',
trailing: const LunaIconButton(icon: LunaIcons.ARROW_RIGHT),
onTap: SettingsRoutes.DEBUG_MENU_UI.go,
),
const LunaHeader(text: 'Boxes'),
LunaBlock(
title: 'Clear Alerts Box',
onTap: () async {
await LunaBox.alerts.clear();
showLunaSuccessSnackBar(
title: 'Cleared',
message: 'Cleared Alerts Box',
);
},
),
const LunaHeader(text: 'Toasts'),
LunaBlock(
title: 'Info',
onTap: () async => showLunaInfoSnackBar(
title: 'Info',
message: null,
),
),
LunaBlock(
title: 'Success',
onTap: () async => showLunaSuccessSnackBar(
title: 'Success',
message: null,
),
),
LunaBlock(
title: 'Error',
onTap: () async => showLunaErrorSnackBar(
title: 'Error',
message: null,
),
),
],
);
}
}

View File

@@ -18,14 +18,14 @@ class _State extends State<DonationsThankYouRoute>
Widget build(BuildContext context) {
return LunaScaffold(
scaffoldKey: _scaffoldKey,
appBar: _appBar() as PreferredSizeWidget?,
appBar: _appBar(),
body: _body(),
);
}
Widget _appBar() {
PreferredSizeWidget _appBar() {
return LunaAppBar(
title: 'Donations',
title: 'settings.Donations'.tr(),
scrollControllers: [scrollController],
);
}
@@ -35,11 +35,8 @@ class _State extends State<DonationsThankYouRoute>
controller: scrollController,
children: [
LunaHeader(
text: 'Thank You',
subtitle: [
"Thank you for supporting the open-source community!",
"Donations are never expected or assumed, so thank you for giving back and helping LunaSea remain free, forever!",
].join("\n\n"),
text: 'lunasea.ThankYou'.tr(),
subtitle: 'lunasea.ThankYouMessage'.tr(),
),
],
);

View File

@@ -27,7 +27,7 @@ class _State extends State<DonationsRoute> with LunaScrollControllerMixin {
Widget _appBar() {
return LunaAppBar(
title: 'Donations',
title: 'settings.Donations'.tr(),
scrollControllers: [scrollController],
);
}
@@ -45,7 +45,7 @@ class _State extends State<DonationsRoute> with LunaScrollControllerMixin {
} else {
return LunaMessage.goBack(
context: context,
text: 'Not Available',
text: 'settings.NotAvailable'.tr(),
);
}
},

View File

@@ -28,7 +28,7 @@ class _State extends State<NotificationsRoute> with LunaScrollControllerMixin {
Widget _appBar() {
return LunaAppBar(
title: 'Notifications',
title: 'settings.Notifications'.tr(),
scrollControllers: [scrollController],
);
}
@@ -41,10 +41,9 @@ class _State extends State<NotificationsRoute> with LunaScrollControllerMixin {
future: LunaFirebaseMessaging().areNotificationsAllowed(),
builder: (context, AsyncSnapshot<bool> snapshot) {
if (snapshot.hasData && !snapshot.data!)
return const LunaBanner(
headerText: 'Not Authorized',
bodyText:
'LunaSea is not authorized to show notifications. Please go to your device\'s settings to enable notifications.',
return LunaBanner(
headerText: 'settings.NotAuthorized'.tr(),
bodyText: 'settings.NotAuthorizedMessage'.tr(),
icon: Icons.error_outline_rounded,
iconColor: LunaColours.red,
);
@@ -53,8 +52,8 @@ class _State extends State<NotificationsRoute> with LunaScrollControllerMixin {
),
SettingsBanners.NOTIFICATIONS_MODULE_SUPPORT.banner(),
LunaBlock(
title: 'Getting Started',
body: const [TextSpan(text: 'Information & Setup Instructions')],
title: 'settings.GettingStarted'.tr(),
body: [TextSpan(text: 'settings.GettingStartedDescription'.tr())],
trailing: const LunaIconButton.arrow(),
onTap: LunaLinkedContent.NOTIFICATIONS_DOC.launch,
),

View File

@@ -3,7 +3,6 @@ import 'package:lunasea/core.dart';
import 'package:lunasea/firebase/core.dart';
import 'package:lunasea/firebase/messaging.dart';
import 'package:lunasea/router/routes/settings.dart';
import 'package:lunasea/system/flavor.dart';
import 'package:lunasea/system/in_app_purchase/in_app_purchase.dart';
class SettingsRoute extends StatefulWidget {
@@ -22,7 +21,7 @@ class _State extends State<SettingsRoute> with LunaScrollControllerMixin {
Widget build(BuildContext context) {
return LunaScaffold(
scaffoldKey: _scaffoldKey,
appBar: _appBar() as PreferredSizeWidget?,
appBar: _appBar(),
drawer: _drawer(),
body: _body(),
);
@@ -30,7 +29,7 @@ class _State extends State<SettingsRoute> with LunaScrollControllerMixin {
Widget _drawer() => LunaDrawer(page: LunaModule.SETTINGS.key);
Widget _appBar() {
PreferredSizeWidget _appBar() {
return LunaAppBar(
useDrawer: true,
scrollControllers: [scrollController],
@@ -88,13 +87,6 @@ class _State extends State<SettingsRoute> with LunaScrollControllerMixin {
trailing: const LunaIconButton(icon: Icons.settings_rounded),
onTap: SettingsRoutes.SYSTEM.go,
),
if (LunaFlavor.CANDIDATE.isRunningFlavor())
LunaBlock(
title: 'settings.DebugMenu'.tr(),
body: [TextSpan(text: 'settings.DebugMenuDescription'.tr())],
trailing: const LunaIconButton(icon: Icons.bug_report_rounded),
onTap: SettingsRoutes.DEBUG_MENU.go,
),
],
);
}

View File

@@ -26,12 +26,12 @@ class _State extends State<SystemRoute> with LunaScrollControllerMixin {
Widget build(BuildContext context) {
return LunaScaffold(
scaffoldKey: _scaffoldKey,
appBar: _appBar() as PreferredSizeWidget?,
appBar: _appBar(),
body: _body(),
);
}
Widget _appBar() {
PreferredSizeWidget _appBar() {
return LunaAppBar(
title: 'settings.System'.tr(),
scrollControllers: [scrollController],

View File

@@ -69,7 +69,7 @@ class _State extends ConsumerState<BuildDetails> {
if (updates.hasError) {
return LunaButton.text(
icon: LunaIcons.ERROR,
text: 'Error',
text: 'lunasea.Error'.tr(),
);
}
if (updates.connectionState == ConnectionState.done && updates.hasData) {

View File

@@ -24,14 +24,14 @@ class _State extends State<SystemLogsDetailsRoute>
Widget build(BuildContext context) {
return LunaScaffold(
scaffoldKey: _scaffoldKey,
appBar: _appBar() as PreferredSizeWidget?,
appBar: _appBar(),
body: _body(),
);
}
Widget _appBar() {
PreferredSizeWidget _appBar() {
return LunaAppBar(
title: '${widget.type?.title ?? 'All'} Logs',
title: 'settings.Logs'.tr(),
scrollControllers: [scrollController],
);
}
@@ -42,7 +42,7 @@ class _State extends State<SystemLogsDetailsRoute>
if (logs.isEmpty) {
return LunaMessage.goBack(
context: context,
text: 'No Logs Found',
text: 'settings.NoLogsFound'.tr(),
);
}
return LunaListViewBuilder(

View File

@@ -22,15 +22,15 @@ class _State extends State<SystemLogsRoute> with LunaScrollControllerMixin {
Widget build(BuildContext context) {
return LunaScaffold(
scaffoldKey: _scaffoldKey,
appBar: _appBar() as PreferredSizeWidget?,
appBar: _appBar(),
body: _body(),
bottomNavigationBar: _bottomActionBar(),
);
}
Widget _appBar() {
PreferredSizeWidget _appBar() {
return LunaAppBar(
title: 'Logs',
title: 'settings.Logs'.tr(),
scrollControllers: [scrollController],
);
}
@@ -49,8 +49,8 @@ class _State extends State<SystemLogsRoute> with LunaScrollControllerMixin {
controller: scrollController,
children: [
LunaBlock(
title: 'All Logs',
body: const [TextSpan(text: 'View Logs of All Types')],
title: 'settings.AllLogs'.tr(),
body: [TextSpan(text: 'settings.AllLogsDescription'.tr())],
trailing: const LunaIconButton(icon: Icons.developer_mode_rounded),
onTap: () async => _viewLogs(null),
),
@@ -95,7 +95,7 @@ class _State extends State<SystemLogsRoute> with LunaScrollControllerMixin {
Widget _clearLogs() {
return LunaButton.text(
text: 'Clear',
text: 'settings.Clear'.tr(),
icon: LunaIcons.DELETE,
color: LunaColours.red,
onTap: () async {
@@ -103,8 +103,8 @@ class _State extends State<SystemLogsRoute> with LunaScrollControllerMixin {
if (result) {
LunaLogger().clear();
showLunaSuccessSnackBar(
title: 'Logs Cleared',
message: 'All recorded logs have been cleared',
title: 'settings.LogsCleared'.tr(),
message: 'settings.LogsClearedDescription'.tr(),
);
}
},
@@ -114,20 +114,16 @@ class _State extends State<SystemLogsRoute> with LunaScrollControllerMixin {
Widget _exportLogs() {
return Builder(
builder: (context) => LunaButton.text(
text: 'Export',
text: 'settings.Export'.tr(),
icon: LunaIcons.DOWNLOAD,
onTap: () async {
showLunaInfoSnackBar(
title: 'Exporting Logs',
message: 'Please wait...',
);
String data = await LunaLogger().export();
bool result = await LunaFileSystem()
.save(context, 'logs.json', utf8.encode(data));
if (result)
showLunaSuccessSnackBar(
title: 'Saved Logs',
message: 'Logs have been successfully saved');
title: 'settings.ExportedLogs'.tr(),
message: 'settings.ExportedLogsMessage'.tr());
},
),
);

View File

@@ -39,11 +39,11 @@ class SettingsSystemLogTile extends StatelessWidget {
],
expandedTableContent: [
if (log.className != null && log.className!.isNotEmpty)
LunaTableContent(title: 'Class', body: log.className),
LunaTableContent(title: 'settings.Class'.tr(), body: log.className),
if (log.methodName != null && log.methodName!.isNotEmpty)
LunaTableContent(title: 'Method', body: log.methodName),
LunaTableContent(title: 'settings.Method'.tr(), body: log.methodName),
if (log.error != null && log.error!.isNotEmpty)
LunaTableContent(title: 'Exception', body: log.error),
LunaTableContent(title: 'settings.Exception'.tr(), body: log.error),
],
);
}

View File

@@ -49,8 +49,6 @@ import 'package:lunasea/modules/settings/routes/configuration_tautulli/pages/def
import 'package:lunasea/modules/settings/routes/configuration_tautulli/pages/headers.dart';
import 'package:lunasea/modules/settings/routes/configuration_tautulli/route.dart';
import 'package:lunasea/modules/settings/routes/configuration_wake_on_lan/route.dart';
import 'package:lunasea/modules/settings/routes/debug_menu/pages/ui.dart';
import 'package:lunasea/modules/settings/routes/debug_menu/route.dart';
import 'package:lunasea/modules/settings/routes/donations/pages/thank_you.dart';
import 'package:lunasea/modules/settings/routes/donations/route.dart';
import 'package:lunasea/modules/settings/routes/notifications/route.dart';
@@ -114,8 +112,6 @@ enum SettingsRoutes with LunaRoutesMixin {
CONFIGURATION_TAUTULLI_CONNECTION_DETAILS_HEADERS('headers'),
CONFIGURATION_TAUTULLI_DEFAULT_PAGES('default_pages'),
CONFIGURATION_WAKE_ON_LAN('wake_on_lan'),
DEBUG_MENU('debug_menu'),
DEBUG_MENU_UI('ui'),
DONATIONS('donations'),
DONATIONS_THANK_YOU('thank_you'),
NOTIFICATIONS('notifications'),
@@ -269,10 +265,6 @@ enum SettingsRoutes with LunaRoutesMixin {
return route(widget: const ConfigurationTautulliDefaultPagesRoute());
case SettingsRoutes.CONFIGURATION_WAKE_ON_LAN:
return route(widget: const ConfigurationWakeOnLANRoute());
case SettingsRoutes.DEBUG_MENU:
return route(widget: const DebugMenuRoute());
case SettingsRoutes.DEBUG_MENU_UI:
return route(widget: const DebugMenuUIRoute());
case SettingsRoutes.DONATIONS:
return route(widget: const DonationsRoute());
case SettingsRoutes.DONATIONS_THANK_YOU:
@@ -302,7 +294,6 @@ enum SettingsRoutes with LunaRoutesMixin {
return [
SettingsRoutes.ACCOUNT.routes,
SettingsRoutes.CONFIGURATION.routes,
SettingsRoutes.DEBUG_MENU.routes,
SettingsRoutes.DONATIONS.routes,
SettingsRoutes.NOTIFICATIONS.routes,
SettingsRoutes.PROFILES.routes,
@@ -416,10 +407,6 @@ enum SettingsRoutes with LunaRoutesMixin {
SettingsRoutes
.CONFIGURATION_TAUTULLI_CONNECTION_DETAILS_HEADERS.routes,
];
case SettingsRoutes.DEBUG_MENU:
return [
SettingsRoutes.DEBUG_MENU_UI.routes,
];
case SettingsRoutes.DONATIONS:
return [
SettingsRoutes.DONATIONS_THANK_YOU.routes,

View File

@@ -36,6 +36,8 @@
"lunasea.DownloadClient": "Download Client",
"lunasea.Edge": "Edge",
"lunasea.Error": "Error",
"lunasea.EverySecond": "Every Second",
"lunasea.EverySeconds": "Every {} Seconds",
"lunasea.ExternalModules": "External Modules",
"lunasea.Features": "Features",
"lunasea.Fixes": "Fixes",
@@ -49,6 +51,7 @@
"lunasea.IncorrectEncryptionKey": "Incorrect encryption key",
"lunasea.Internal": "Internal",
"lunasea.InvalidFileTypeSelected": "Invalid File Type Selected",
"lunasea.Items": "{} Items",
"lunasea.JustNow": "Just Now",
"lunasea.Minutes": "{} Minutes",
"lunasea.MinutesAgo": "{} Minutes Ago",
@@ -64,6 +67,7 @@
"lunasea.OneDayAgo": "1 Day Ago",
"lunasea.OneHour": "1 Hour",
"lunasea.OneHourAgo": "1 Hour Ago",
"lunasea.OneItem": "1 Item",
"lunasea.OneMinute": "1 Minute",
"lunasea.OneMinuteAgo": "1 Minute Ago",
"lunasea.OneMonth": "1 Month",
@@ -92,6 +96,8 @@
"lunasea.Settings": "Settings",
"lunasea.Stable": "Stable",
"lunasea.StartingView": "Starting View",
"lunasea.ThankYou": "Thank You",
"lunasea.ThankYouMessage": "Thank you for supporting the open-source community!",
"lunasea.Today": "Today",
"lunasea.TransactionFailure": "Transaction Failure",
"lunasea.TryAgain": "Try Again",

View File

@@ -25,6 +25,8 @@
"radarr.DigitalRelease": "Digital Release",
"radarr.DirectoryNotFound": "Directory Not Found",
"radarr.Discover": "Discover",
"radarr.DiscoverSuggestions": "Discover Suggestions",
"radarr.DiscoverSuggestionsDescription": "Add Suggested Releases in Discover",
"radarr.Disks": "Disks",
"radarr.DownloadFailed": "Download Failed",
"radarr.DownloadIgnored": "Download Ignored",
@@ -59,6 +61,7 @@
"radarr.MoveFilesDescription": "Would you like to move the files?",
"radarr.MoveFull": "Move Files",
"radarr.Movie": "Movie",
"radarr.MovieDetails": "Movie Details",
"radarr.Movies": "Movies",
"radarr.MovieFileDeleted": "Movie File Deleted",
"radarr.MovieFileRenamed": "Movie File Renamed",
@@ -81,6 +84,7 @@
"radarr.QualityProfile": "Quality Profile",
"radarr.Queue": "Queue",
"radarr.QueueDescription": "View Active & Queued Content",
"radarr.QueueSize": "Queue Size",
"radarr.Quick": "Quick",
"radarr.RefreshMovie": "Refresh Movie",
"radarr.Rejected": "Rejected",

View File

@@ -1,23 +1,37 @@
{
"search.Age": "Age",
"search.AllSubcategories": "All Subcategories",
"search.Alphabetical": "Alphabetical",
"search.Category": "Category",
"search.Categories": "Categories",
"search.Comments": "Comments",
"search.Download": "Download",
"search.Downloading": "Downloading…",
"search.DownloadingNZBToDevice": "Downloading NZB to your device",
"search.DownloadToDevice": "Download to Device",
"search.FailedToDownloadNZB": "Failed to Download NZB",
"search.FailedToSend": "Failed to Send",
"search.NoCategoriesFound": "No Categories Found",
"search.NoResultsFound": "No Results Found",
"search.NoSubcategoriesFound": "No Subcategories Found",
"search.Results": "Results",
"search.Search": "Search",
"search.SentNZBData": "Sent NZB Data",
"search.SentTo": "Sent to {}",
"search.Size": "Size",
"search.Subcategories": "Subcategories"
}
"search.AddIndexer": "Add Indexer",
"search.Age": "Age",
"search.AllSubcategories": "All Subcategories",
"search.Alphabetical": "Alphabetical",
"search.Category": "Category",
"search.Categories": "Categories",
"search.Comments": "Comments",
"search.DeleteIndexer": "Delete Indexer",
"search.Download": "Download",
"search.Downloading": "Downloading…",
"search.DownloadingNZBToDevice": "Downloading NZB to your device",
"search.DownloadToDevice": "Download to Device",
"search.EditIndexer": "Edit Indexer",
"search.FailedToAddIndexer": "Failed to Add indexer",
"search.FailedToDownloadNZB": "Failed to Download NZB",
"search.FailedToSend": "Failed to Send",
"search.HideAdultCategories": "Hide Adult Categories",
"search.HideAdultCategoriesDescription": "Hide Adult Content",
"search.IndexerAPIHost": "Indexer API Host",
"search.IndexerAPIKey": "Indexer API Key",
"search.IndexerAdded": "Indexer Added",
"search.IndexerDeleted": "Indexer Deleted",
"search.IndexerNotFound": "Indexer Not Found",
"search.NoCategoriesFound": "No Categories Found",
"search.NoIndexersFound": "No Indexers Found",
"search.NoResultsFound": "No Results Found",
"search.NoSubcategoriesFound": "No Subcategories Found",
"search.Results": "Results",
"search.Search": "Search",
"search.SentNZBData": "Sent NZB Data",
"search.SentTo": "Sent to {}",
"search.ShowLinks": "Show Links",
"search.ShowLinksDescription": "Show Download and Comments Links",
"search.Size": "Size",
"search.Subcategories": "Subcategories"
}

View File

@@ -15,6 +15,8 @@
"settings.AddProfileDescription": "Add a New Profile",
"settings.AddedProfile": "Added Profile",
"settings.AllFieldsAreRequired": "All fields are required",
"settings.AllLogs": "All Logs",
"settings.AllLogsDescription": "View Logs of All Types",
"settings.AmoledTheme": "AMOLED Theme",
"settings.AmoledThemeBorders": "AMOLED Theme Borders",
"settings.AmoledThemeBordersDescription": "Add Subtle Borders Across the UI",
@@ -53,9 +55,12 @@
"settings.BuildChannels": "Build Channels",
"settings.BuildChannelsDescription": "Learn About Additional Build Channels",
"settings.CalendarSettings": "Calendar Settings",
"settings.CalendarSettingsDescription": "Customize the Unified Calendar",
"settings.ChangedProfile": "Changed Profile",
"settings.Channel": "Channel",
"settings.Class": "Class",
"settings.CleanSlate": "Clean Slate",
"settings.Clear": "Clear",
"settings.ClearConfiguration": "Clear Configuration",
"settings.ClearConfigurationHint1": "Are you sure you want to clear your configuration?",
"settings.ClearConfigurationHint2": "You will be starting from a clean slate, please ensure you backup your current configuration first!",
@@ -76,6 +81,9 @@
"settings.ConnectionDetails": "Connection Details",
"settings.ConnectionDetailsDescription": "Connection Details for {}",
"settings.ConnectionTestFailed": "Connection Test Failed",
"settings.CopiedURLFor": "Copied URL for {}",
"settings.CopiedDeviceURL": "Copied your device-based URL to the clipboard",
"settings.CopiedUserURL": "Copied your user-based URL to the clipboard",
"settings.CurrentPassword": "Current Password",
"settings.Custom": "Custom…",
"settings.CustomHeader": "Custom Header",
@@ -116,6 +124,7 @@
"settings.DeleteModuleSuccess": "Module Deleted",
"settings.DeleteProfile": "Delete Profile",
"settings.DeleteProfileDescription": "Delete an Existing Profile",
"settings.Device": "Device",
"settings.DiscordDescription": "Request Features & Get Support",
"settings.DismissBanners": "Dismiss Banners",
"settings.DismissBannersHint1": "Are you sure you want to dismiss all tooltip banners?",
@@ -139,6 +148,10 @@
"settings.EnableModule": "Enable {}",
"settings.EnabledProfile": "Enabled Profile",
"settings.EncryptionKey": "Encryption Key",
"settings.Exception": "Exception",
"settings.Export": "Export",
"settings.ExportedLogs": "Exported Logs",
"settings.ExportedLogsMessage": "Logs have been successfully exported",
"settings.FailedToClearImageCache": "Failed to Clear Image Cache",
"settings.FailedToClearImageCacheDescription": "The image cache could not be cleared",
"settings.FailedToDeleteAccount": "Failed to Delete Account",
@@ -149,6 +162,8 @@
"settings.FutureDays": "Future Days",
"settings.General": "General",
"settings.GeneralDescription": "Customize LunaSea",
"settings.GettingStarted": "Getting Started",
"settings.GettingStartedDescription": "Information & Setup Instructions",
"settings.GitHubDescription": "View the Source Code",
"settings.HeaderAdded": "Header Added",
"settings.HeaderDeleted": "Header Deleted",
@@ -179,7 +194,10 @@
"settings.Localization": "Localization",
"settings.LocalizationDescription": "Customize to your Locale",
"settings.Logs": "Logs",
"settings.LogsCleared": "Logs Cleared",
"settings.LogsClearedDescription": "All recorded logs have been cleared",
"settings.LogsDescription": "View, Export, and Clear Logs",
"settings.Method": "Method",
"settings.MACAddress": "MAC Address",
"settings.MACAddressHint1": "This is the MAC address of the machine that you want to wake up",
"settings.MACAddressHint2": "MAC addresses contain six two-digit hexadecimal nibbles (an octet)",
@@ -192,12 +210,16 @@
"settings.Network": "Network",
"settings.NetworkDescription": "Customize Network Features",
"settings.NewPassword": "New Password",
"settings.NotAuthorized": "Not Authorized",
"settings.NotAuthorizedMessage": "LunaSea is not authorized to show notifications. Please go to your device's settings to enable notifications.",
"settings.NotAvailable": "Not Available",
"settings.Notifications": "Notifications",
"settings.NotificationsDescription": "Set up Webhooks for Push Notifications",
"settings.NoAdditionalProfilesAdded": "No additional profiles have been added",
"settings.NoBackupsFound": "No Backups Found",
"settings.NoExternalModulesFound": "No External Modules Found",
"settings.NoHeadersAdded": "No Headers Added",
"settings.NoLogsFound": "No Logs Found",
"settings.NoProfilesFound": "No Profiles Found",
"settings.OpenDrawerOnBackAction": "Open Drawer on Back Action",
"settings.OpenDrawerOnBackActionDescription": "Open the drawer instead of closing LunaSea",
@@ -268,6 +290,7 @@
"settings.UpToDate": "Up To Date",
"settings.Use24HourTime": "Use 24 Hour Time",
"settings.Use24HourTimeDescription": "Show Timestamps in 24 Hour Style",
"settings.User": "User",
"settings.Username": "Username",
"settings.UsernameValidation": "Username Required",
"settings.Version": "Version",

View File

@@ -133,6 +133,7 @@
"sonarr.Queue": "Queue",
"sonarr.Queued": "Queued",
"sonarr.QueueDescription": "View Active & Queued Content",
"sonarr.QueueSize": "Queue Size",
"sonarr.Reason": "Reason",
"sonarr.RefreshSeries": "Refresh Series",
"sonarr.Rejected": "Rejected",

View File

@@ -1,6 +1,7 @@
{
"tautulli.Activity": "Activity",
"tautulli.ActivityDetails": "Activity Details",
"tautulli.ActivityRefreshRate": "Activity Refresh Rate",
"tautulli.Audio": "Audio",
"tautulli.BackingUpConfiguration": "Backing Up Configuration…",
"tautulli.BackingUpConfigurationDescription": "Backing up your configuration in the background",
@@ -15,6 +16,7 @@
"tautulli.Converting": "Converting",
"tautulli.Container": "Container",
"tautulli.Copy": "Copy",
"tautulli.DefaultTerminationMessage": "Default Termination Message",
"tautulli.DeleteCache": "Delete Cache",
"tautulli.DeleteImageCache": "Delete Image Cache",
"tautulli.DeleteTemporarySessions": "Delete Temporary Sessions",
@@ -34,9 +36,12 @@
"tautulli.Duration": "Duration",
"tautulli.Episode": "Episode {}",
"tautulli.ETA": "ETA",
"tautulli.Graphs": "Graphs",
"tautulli.History": "History",
"tautulli.Library": "Library",
"tautulli.LibraryDetails": "Library Details",
"tautulli.Location": "Location",
"tautulli.MediaDetails": "Media Details",
"tautulli.Metadata": "Metadata",
"tautulli.More": "More",
"tautulli.None": "None",
@@ -51,6 +56,8 @@
"tautulli.SessionsOne": "1 Session",
"tautulli.SessionsMany": "{} Sessions",
"tautulli.Speed": "Speed: {}x",
"tautulli.Statistics": "Statistics",
"tautulli.StatisticsItemCount": "Statistics Item Count",
"tautulli.Stream": "Stream",
"tautulli.Subtitle": "Subtitle",
"tautulli.Terminate": "Terminate",
@@ -66,6 +73,7 @@
"tautulli.Transcodes": "Transcodes",
"tautulli.User": "User",
"tautulli.Users": "Users",
"tautulli.UserDetails": "User Details",
"tautulli.Video": "Video",
"tautulli.ViewWebGUI": "View Web GUI",
"tautulli.Year": "Year"