diff --git a/assets/localization/en.json b/assets/localization/en.json index a11e590a..671f6632 100644 --- a/assets/localization/en.json +++ b/assets/localization/en.json @@ -45,6 +45,7 @@ "settings.BroadcastAddressHint2": "Typically this is the IP address of your machine with the last octet set to 255", "settings.BroadcastAddressHint3": "Given an example machine IP address of 192.168.1.111, the resulting broadcast IP address is 192.168.1.255", "settings.BroadcastAddressValidation": "Invalid Broadcast Address", + "settings.CalendarSettings": "Calendar Settings", "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!", @@ -66,6 +67,8 @@ "settings.CustomHeader": "Custom Header", "settings.CustomHeaders": "Custom Headers", "settings.CustomHeadersDescription": "Add Custom Headers to Requests", + "settings.DaysOne": "1 Day", + "settings.DaysCount": "{} Days", "settings.DefaultPage": "Default Page", "settings.DefaultPages": "Default Pages", "settings.DefaultPagesDescription": "Set Default Landing Pages", @@ -111,6 +114,7 @@ "settings.EmailSentFailure": "Failed to Reset Password", "settings.EmailSentSuccess": "Email Sent", "settings.EmailSentSuccessMessage": "An email to reset your password has been sent!", + "settings.EnableModule": "Enable {}", "settings.EnabledProfile": "Enabled Profile", "settings.EncryptionKey": "Encryption Key", "settings.FailedToDeleteAccount": "Failed to Delete Account", @@ -118,6 +122,7 @@ "settings.FeedbackBoardDescription": "Request New Features", "settings.FilterCategory": "Filter Category", "settings.ForgotYourPassword": "Forgot Your Password?", + "settings.FutureDays": "Future Days", "settings.GitHubDescription": "View the Source Code", "settings.HeaderAdded": "Header Added", "settings.HeaderDeleted": "Header Deleted", @@ -125,6 +130,7 @@ "settings.HeaderKeyValidation": "Header Key Required", "settings.HeaderValue": "Header Value", "settings.HeaderValueValidation": "Header Value Required", + "settings.Home": "Home", "settings.Host": "Host", "settings.HostHint1": "This is the URL in which you access the web GUI for the service", "settings.HostHint2": "You must include either http:// or https://", @@ -162,14 +168,21 @@ "settings.NoHeadersAdded": "No Headers Added", "settings.OpenLinksIn": "Open Links In…", "settings.Password": "Password", + "settings.PasswordHint1": "If your password includes special characters, considering adding a basic authentication header with your username and password instead for better support", "settings.PasswordValidation": "Password Required", + "settings.PastDays": "Past Days", + "settings.PastDaysInScheduleView": "Past Days In Schedule View", "settings.Profiles": "Profiles", + "settings.ProfilesBannerLine1": "Profiles allow you to add multiple instances of modules into LunaSea. You can switch between profiles in the main navigation drawer.", + "settings.ProfilesBannerLine2": "Newznab indexer searching and external modules are enabled and shared across all profiles.", "settings.ProfilesDescription": "Manage Your Profiles", "settings.ProfileAlreadyExists": "Profile Already Exists", "settings.ProfileName": "Profile Name", "settings.ProfileNameRequired": "Profile Name Required", "settings.QuickActions": "Quick Actions", "settings.QuickActionsDescription": "Quick Actions on the Home Screen", + "settings.QuickActionsBannerLine1": "Quick actions allow you to quickly jump into modules directly from the home screen or launcher on your device by long pressing LunaSea's icon.", + "settings.QuickActionsBannerLine2": "A limited number of quick actions can be set at a time, and enabling more than your launcher can support will have no effect.", "settings.RedditDescription": "Ask Questions & Get Support", "settings.Register": "Register", "settings.RegisteredFailure": "Failed to Register", @@ -208,6 +221,8 @@ "settings.TestConnection": "Test Connection", "settings.TLSCertificateValidation": "TLS Certificate Validation", "settings.TLSCertificateValidationDescription": "Validate Certificates in TLS Connections", + "settings.Use24HourTime": "Use 24 Hour Time", + "settings.Use24HourTimeDescription": "Show Timestamps in 24 Hour Style", "settings.Username": "Username", "settings.UsernameValidation": "Username Required", "settings.ViewRecentChanges": "View Recent Changes", diff --git a/lib/modules/settings/core/banners.dart b/lib/modules/settings/core/banners.dart index 3cfaccd6..eb74c92f 100644 --- a/lib/modules/settings/core/banners.dart +++ b/lib/modules/settings/core/banners.dart @@ -29,14 +29,14 @@ extension SettingsBannersExtension on SettingsBanners { return 'settings.BannersNotificationModuleSupportBody'.tr(); case SettingsBanners.QUICK_ACTIONS_SUPPORT: return [ - 'Quick actions allow you to quickly jump into modules directly from the home screen or launcher on your device by long pressing LunaSea\'s icon.', - 'A limited number of quick actions can be set at a time, and enabling more than your launcher can support will have no effect.' + 'settings.QuickActionsBannerLine1'.tr(), + 'settings.QuickActionsBannerLine2'.tr(), ].join('\n\n'); case SettingsBanners.PROFILES_SUPPORT: return [ - 'Profiles allow you to add multiple instances of modules into LunaSea. You can switch between profiles in the main navigation drawer.', - 'Newznab indexer searching and external modules are enabled and shared across all profiles.', + 'settings.ProfilesBannerLine1'.tr(), + 'settings.ProfilesBannerLine2'.tr(), ].join('\n\n'); } } diff --git a/lib/modules/settings/routes/configuration_dashboard/pages/calendar_settings.dart b/lib/modules/settings/routes/configuration_dashboard/pages/calendar_settings.dart index 534101e3..df328f91 100644 --- a/lib/modules/settings/routes/configuration_dashboard/pages/calendar_settings.dart +++ b/lib/modules/settings/routes/configuration_dashboard/pages/calendar_settings.dart @@ -36,7 +36,7 @@ class _State extends State<_Widget> with LunaScrollControllerMixin { Widget _appBar() { return LunaAppBar( - title: 'Calendar Settings', + title: 'settings.CalendarSettings'.tr(), scrollControllers: [scrollController], ); } @@ -64,7 +64,7 @@ class _State extends State<_Widget> with LunaScrollControllerMixin { DashboardDatabaseValue _db = DashboardDatabaseValue.CALENDAR_SHOW_PAST_DAYS; return _db.listen( builder: (context, box, widget) => LunaBlock( - title: 'Past Days In Schedule View', + title: 'settings.PastDaysInScheduleView'.tr(), trailing: LunaSwitch( value: _db.data, onChanged: _db.put, @@ -77,9 +77,13 @@ class _State extends State<_Widget> with LunaScrollControllerMixin { DashboardDatabaseValue _db = DashboardDatabaseValue.CALENDAR_DAYS_PAST; return _db.listen( builder: (context, box, widget) => LunaBlock( - title: 'Past Days', + title: 'settings.PastDays'.tr(), body: [ - TextSpan(text: _db.data == 1 ? '1 Day' : '${_db.data} Days'), + TextSpan( + text: _db.data == 1 + ? 'settings.DaysOne'.tr() + : 'settings.DaysCount'.tr(args: [_db.data.toString()]), + ), ], trailing: const LunaIconButton.arrow(), onTap: () async { @@ -95,9 +99,13 @@ class _State extends State<_Widget> with LunaScrollControllerMixin { DashboardDatabaseValue _db = DashboardDatabaseValue.CALENDAR_DAYS_FUTURE; return _db.listen( builder: (context, box, widget) => LunaBlock( - title: 'Future Days', + title: 'settings.FutureDays'.tr(), body: [ - TextSpan(text: _db.data == 1 ? '1 Day' : '${_db.data} Days'), + TextSpan( + text: _db.data == 1 + ? 'settings.DaysOne'.tr() + : 'settings.DaysCount'.tr(args: [_db.data.toString()]), + ), ], trailing: const LunaIconButton.arrow(), onTap: () async { @@ -209,7 +217,7 @@ class _State extends State<_Widget> with LunaScrollControllerMixin { DashboardDatabaseValue _db = DashboardDatabaseValue.CALENDAR_STARTING_SIZE; return _db.listen( builder: (context, box, widget) => LunaBlock( - title: 'Starting Size', + title: 'settings.StartingSize'.tr(), body: [ TextSpan(text: (_db.data as CalendarStartingSize).name), ], diff --git a/lib/modules/settings/routes/configuration_lidarr/route.dart b/lib/modules/settings/routes/configuration_lidarr/route.dart index 5c738209..a06bfd93 100644 --- a/lib/modules/settings/routes/configuration_lidarr/route.dart +++ b/lib/modules/settings/routes/configuration_lidarr/route.dart @@ -57,7 +57,7 @@ class _State extends State<_Widget> with LunaScrollControllerMixin { return ValueListenableBuilder( valueListenable: Database.profiles.box.listenable(), builder: (context, dynamic _, __) => LunaBlock( - title: 'Enable ${LunaModule.LIDARR.name}', + title: 'settings.EnableModule'.tr(args: [LunaModule.LIDARR.name]), trailing: LunaSwitch( value: LunaProfile.current.lidarrEnabled ?? false, onChanged: (value) { diff --git a/lib/modules/settings/routes/configuration_localization/route.dart b/lib/modules/settings/routes/configuration_localization/route.dart index e6d58b7c..dfcd1a73 100644 --- a/lib/modules/settings/routes/configuration_localization/route.dart +++ b/lib/modules/settings/routes/configuration_localization/route.dart @@ -70,8 +70,8 @@ class _State extends State<_Widget> with LunaScrollControllerMixin { LunaDatabaseValue _db = LunaDatabaseValue.USE_24_HOUR_TIME; return _db.listen( builder: (context, _, __) => LunaBlock( - title: 'Use 24 Hour Time', - body: const [TextSpan(text: 'Show Timestamps in 24 Hour Style')], + title: 'settings.Use24HourTime'.tr(), + body: [TextSpan(text: 'settings.Use24HourTimeDescription'.tr())], trailing: LunaSwitch( value: _db.data, onChanged: (value) => _db.put(value), diff --git a/lib/modules/settings/routes/configuration_nzbget/pages/connection_details.dart b/lib/modules/settings/routes/configuration_nzbget/pages/connection_details.dart index 9db760c0..54222e04 100644 --- a/lib/modules/settings/routes/configuration_nzbget/pages/connection_details.dart +++ b/lib/modules/settings/routes/configuration_nzbget/pages/connection_details.dart @@ -37,7 +37,7 @@ class _State extends State<_Widget> with LunaScrollControllerMixin { Widget _appBar() { return LunaAppBar( - title: 'Connection Details', + title: 'settings.ConnectionDetails'.tr(), scrollControllers: [scrollController], ); } @@ -127,13 +127,11 @@ class _State extends State<_Widget> with LunaScrollControllerMixin { prefill: password, extraText: [ LunaDialog.textSpanContent( - text: - '${LunaUI.TEXT_BULLET}\tIf your password includes special characters, considering adding a ', + text: [ + LunaUI.TEXT_BULLET, + 'settings.PasswordHint1'.tr(), + ].join('\t'), ), - LunaDialog.bolded(text: 'basic authentication'), - LunaDialog.textSpanContent( - text: - ' header with your username and password instead for better support'), ], ); if (_values.item1) { @@ -153,21 +151,23 @@ class _State extends State<_Widget> with LunaScrollControllerMixin { ProfileHiveObject _profile = LunaProfile.current; if (_profile.nzbgetHost == null || _profile.nzbgetHost!.isEmpty) { showLunaErrorSnackBar( - title: 'Host Required', - message: 'Host is required to connect to NZBGet', + title: 'settings.HostRequired'.tr(), + message: 'settings.HostRequiredMessage' + .tr(args: [LunaModule.NZBGET.name]), ); return; } NZBGetAPI.from(LunaProfile.current) .testConnection() .then((_) => showLunaSuccessSnackBar( - title: 'Connected Successfully', - message: 'NZBGet is ready to use with LunaSea', + title: 'settings.ConnectedSuccessfully'.tr(), + message: 'settings.ConnectedSuccessfullyMessage' + .tr(args: [LunaModule.NZBGET.name]), )) .catchError((error, trace) { LunaLogger().error('Connection Test Failed', error, trace); showLunaErrorSnackBar( - title: 'Connection Test Failed', + title: 'settings.ConnectionTestFailed'.tr(), error: error, ); }); diff --git a/lib/modules/settings/routes/configuration_nzbget/route.dart b/lib/modules/settings/routes/configuration_nzbget/route.dart index b9f72c6a..6f34616c 100644 --- a/lib/modules/settings/routes/configuration_nzbget/route.dart +++ b/lib/modules/settings/routes/configuration_nzbget/route.dart @@ -57,7 +57,7 @@ class _State extends State<_Widget> with LunaScrollControllerMixin { return ValueListenableBuilder( valueListenable: Database.profiles.box.listenable(), builder: (context, dynamic _, __) => LunaBlock( - title: 'Enable ${LunaModule.NZBGET.name}', + title: 'settings.EnableModule'.tr(args: [LunaModule.NZBGET.name]), trailing: LunaSwitch( value: LunaProfile.current.nzbgetEnabled ?? false, onChanged: (value) { @@ -72,8 +72,13 @@ class _State extends State<_Widget> with LunaScrollControllerMixin { Widget _connectionDetailsPage() { return LunaBlock( - title: 'Connection Details', - body: const [TextSpan(text: 'Connection Details for NZBGet')], + title: 'settings.ConnectionDetails'.tr(), + body: [ + TextSpan( + text: 'settings.ConnectionDetailsDescription' + .tr(args: [LunaModule.NZBGET.name]), + ), + ], trailing: const LunaIconButton.arrow(), onTap: () async { SettingsConfigurationNZBGetConnectionDetailsRouter() diff --git a/lib/modules/settings/routes/configuration_overseerr/pages/connection_details.dart b/lib/modules/settings/routes/configuration_overseerr/pages/connection_details.dart index 7819be98..6ec3f0f6 100644 --- a/lib/modules/settings/routes/configuration_overseerr/pages/connection_details.dart +++ b/lib/modules/settings/routes/configuration_overseerr/pages/connection_details.dart @@ -37,7 +37,7 @@ class _State extends State<_Widget> with LunaScrollControllerMixin { Widget _appBar() { return LunaAppBar( - title: 'Connection Details', + title: 'settings.ConnectionDetails'.tr(), scrollControllers: [scrollController], ); } @@ -119,15 +119,17 @@ class _State extends State<_Widget> with LunaScrollControllerMixin { ProfileHiveObject _profile = LunaProfile.current; if (_profile.overseerrHost == null || _profile.overseerrHost!.isEmpty) { showLunaErrorSnackBar( - title: 'Host Required', - message: 'Host is required to connect to Overseerr', + title: 'settings.HostRequired'.tr(), + message: 'settings.HostRequiredMessage' + .tr(args: [LunaModule.OVERSEERR.name]), ); return; } if (_profile.overseerrKey == null || _profile.overseerrKey!.isEmpty) { showLunaErrorSnackBar( - title: 'API Key Required', - message: 'API key is required to connect to Overseerr', + title: 'settings.ApiKeyRequired'.tr(), + message: 'settings.ApiKeyRequiredMessage' + .tr(args: [LunaModule.OVERSEERR.name]), ); return; } @@ -139,19 +141,16 @@ class _State extends State<_Widget> with LunaScrollControllerMixin { .getStatus() .then( (_) => showLunaSuccessSnackBar( - title: 'Connected Successfully', - message: 'Overseerr is ready to use with LunaSea', + title: 'settings.ConnectedSuccessfully'.tr(), + message: 'settings.ConnectedSuccessfullyMessage' + .tr(args: [LunaModule.OVERSEERR.name]), ), ) .catchError( (error, trace) { - LunaLogger().error( - 'Connection Test Failed', - error, - trace, - ); + LunaLogger().error('Connection Test Failed', error, trace); showLunaErrorSnackBar( - title: 'Connection Test Failed', + title: 'settings.ConnectionTestFailed'.tr(), error: error, ); }, diff --git a/lib/modules/settings/routes/configuration_radarr/pages/connection_details.dart b/lib/modules/settings/routes/configuration_radarr/pages/connection_details.dart index cd81673d..6ddc66bd 100644 --- a/lib/modules/settings/routes/configuration_radarr/pages/connection_details.dart +++ b/lib/modules/settings/routes/configuration_radarr/pages/connection_details.dart @@ -37,7 +37,7 @@ class _State extends State<_Widget> with LunaScrollControllerMixin { Widget _appBar() { return LunaAppBar( - title: 'Connection Details', + title: 'settings.ConnectionDetails'.tr(), scrollControllers: [scrollController], ); } @@ -119,15 +119,17 @@ class _State extends State<_Widget> with LunaScrollControllerMixin { ProfileHiveObject _profile = LunaProfile.current; if (_profile.radarrHost == null || _profile.radarrHost!.isEmpty) { showLunaErrorSnackBar( - title: 'Host Required', - message: 'Host is required to connect to Radarr', + title: 'settings.HostRequired'.tr(), + message: 'settings.HostRequiredMessage' + .tr(args: [LunaModule.RADARR.name]), ); return; } if (_profile.radarrKey == null || _profile.radarrKey!.isEmpty) { showLunaErrorSnackBar( - title: 'API Key Required', - message: 'API key is required to connect to Radarr', + title: 'settings.ApiKeyRequired'.tr(), + message: 'settings.ApiKeyRequiredMessage' + .tr(args: [LunaModule.RADARR.name]), ); return; } @@ -140,8 +142,9 @@ class _State extends State<_Widget> with LunaScrollControllerMixin { .status() .then( (_) => showLunaSuccessSnackBar( - title: 'Connected Successfully', - message: 'Radarr is ready to use with LunaSea', + title: 'settings.ConnectedSuccessfully'.tr(), + message: 'settings.ConnectedSuccessfullyMessage' + .tr(args: [LunaModule.RADARR.name]), ), ) .catchError( @@ -152,7 +155,7 @@ class _State extends State<_Widget> with LunaScrollControllerMixin { trace, ); showLunaErrorSnackBar( - title: 'Connection Test Failed', + title: 'settings.ConnectionTestFailed'.tr(), error: error, ); }, diff --git a/lib/modules/settings/routes/configuration_radarr/pages/default_pages.dart b/lib/modules/settings/routes/configuration_radarr/pages/default_pages.dart index dcedb2a0..47780c8a 100644 --- a/lib/modules/settings/routes/configuration_radarr/pages/default_pages.dart +++ b/lib/modules/settings/routes/configuration_radarr/pages/default_pages.dart @@ -35,7 +35,7 @@ class _State extends State<_Widget> with LunaScrollControllerMixin { Widget _appBar() { return LunaAppBar( - title: 'Default Pages', + title: 'settings.DefaultPages'.tr(), scrollControllers: [scrollController], ); } @@ -56,7 +56,7 @@ class _State extends State<_Widget> with LunaScrollControllerMixin { RadarrDatabaseValue _db = RadarrDatabaseValue.NAVIGATION_INDEX; return _db.listen( builder: (context, box, _) => LunaBlock( - title: 'Home', + title: 'settings.Home'.tr(), body: [TextSpan(text: RadarrNavigationBar.titles[_db.data])], trailing: LunaIconButton(icon: RadarrNavigationBar.icons[_db.data]), onTap: () async { diff --git a/lib/modules/settings/routes/profiles.dart b/lib/modules/settings/routes/profiles.dart index e252d0b8..08c41a56 100644 --- a/lib/modules/settings/routes/profiles.dart +++ b/lib/modules/settings/routes/profiles.dart @@ -32,7 +32,7 @@ class _State extends State<_Widget> with LunaScrollControllerMixin { Widget _appBar() { return LunaAppBar( - title: 'Profiles', + title: 'settings.Profiles'.tr(), scrollControllers: [scrollController], ); } @@ -68,7 +68,7 @@ class _State extends State<_Widget> with LunaScrollControllerMixin { Widget _enabledProfile() { return LunaDatabaseValue.ENABLED_PROFILE.listen( builder: (context, _, __) => LunaBlock( - title: 'Enabled Profile', + title: 'settings.EnabledProfile'.tr(), body: [TextSpan(text: LunaDatabaseValue.ENABLED_PROFILE.data)], trailing: const LunaIconButton(icon: LunaIcons.USER), onTap: () async { diff --git a/localization/settings/en.json b/localization/settings/en.json index 94df81f4..1ae1e376 100644 --- a/localization/settings/en.json +++ b/localization/settings/en.json @@ -45,6 +45,7 @@ "settings.BroadcastAddressHint2": "Typically this is the IP address of your machine with the last octet set to 255", "settings.BroadcastAddressHint3": "Given an example machine IP address of 192.168.1.111, the resulting broadcast IP address is 192.168.1.255", "settings.BroadcastAddressValidation": "Invalid Broadcast Address", + "settings.CalendarSettings": "Calendar Settings", "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!", @@ -66,6 +67,8 @@ "settings.CustomHeader": "Custom Header", "settings.CustomHeaders": "Custom Headers", "settings.CustomHeadersDescription": "Add Custom Headers to Requests", + "settings.DaysOne": "1 Day", + "settings.DaysCount": "{} Days", "settings.DefaultPage": "Default Page", "settings.DefaultPages": "Default Pages", "settings.DefaultPagesDescription": "Set Default Landing Pages", @@ -111,6 +114,7 @@ "settings.EmailSentFailure": "Failed to Reset Password", "settings.EmailSentSuccess": "Email Sent", "settings.EmailSentSuccessMessage": "An email to reset your password has been sent!", + "settings.EnableModule": "Enable {}", "settings.EnabledProfile": "Enabled Profile", "settings.EncryptionKey": "Encryption Key", "settings.FailedToDeleteAccount": "Failed to Delete Account", @@ -118,6 +122,7 @@ "settings.FeedbackBoardDescription": "Request New Features", "settings.FilterCategory": "Filter Category", "settings.ForgotYourPassword": "Forgot Your Password?", + "settings.FutureDays": "Future Days", "settings.GitHubDescription": "View the Source Code", "settings.HeaderAdded": "Header Added", "settings.HeaderDeleted": "Header Deleted", @@ -125,6 +130,7 @@ "settings.HeaderKeyValidation": "Header Key Required", "settings.HeaderValue": "Header Value", "settings.HeaderValueValidation": "Header Value Required", + "settings.Home": "Home", "settings.Host": "Host", "settings.HostHint1": "This is the URL in which you access the web GUI for the service", "settings.HostHint2": "You must include either http:// or https://", @@ -162,14 +168,21 @@ "settings.NoHeadersAdded": "No Headers Added", "settings.OpenLinksIn": "Open Links In…", "settings.Password": "Password", + "settings.PasswordHint1": "If your password includes special characters, considering adding a basic authentication header with your username and password instead for better support", "settings.PasswordValidation": "Password Required", + "settings.PastDays": "Past Days", + "settings.PastDaysInScheduleView": "Past Days In Schedule View", "settings.Profiles": "Profiles", + "settings.ProfilesBannerLine1": "Profiles allow you to add multiple instances of modules into LunaSea. You can switch between profiles in the main navigation drawer.", + "settings.ProfilesBannerLine2": "Newznab indexer searching and external modules are enabled and shared across all profiles.", "settings.ProfilesDescription": "Manage Your Profiles", "settings.ProfileAlreadyExists": "Profile Already Exists", "settings.ProfileName": "Profile Name", "settings.ProfileNameRequired": "Profile Name Required", "settings.QuickActions": "Quick Actions", "settings.QuickActionsDescription": "Quick Actions on the Home Screen", + "settings.QuickActionsBannerLine1": "Quick actions allow you to quickly jump into modules directly from the home screen or launcher on your device by long pressing LunaSea's icon.", + "settings.QuickActionsBannerLine2": "A limited number of quick actions can be set at a time, and enabling more than your launcher can support will have no effect.", "settings.RedditDescription": "Ask Questions & Get Support", "settings.Register": "Register", "settings.RegisteredFailure": "Failed to Register", @@ -208,6 +221,8 @@ "settings.TestConnection": "Test Connection", "settings.TLSCertificateValidation": "TLS Certificate Validation", "settings.TLSCertificateValidationDescription": "Validate Certificates in TLS Connections", + "settings.Use24HourTime": "Use 24 Hour Time", + "settings.Use24HourTimeDescription": "Show Timestamps in 24 Hour Style", "settings.Username": "Username", "settings.UsernameValidation": "Username Required", "settings.ViewRecentChanges": "View Recent Changes",