diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index afbf2ef..38bd0aa 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -10,4 +10,16 @@ updates: schedule: interval: "weekly" ignore: - - dependency-name: "ht_*" + - dependency-name: "auth_api" + - dependency-name: "auth_client" + - dependency-name: "auth_inmemory" + - dependency-name: "auth_repository" + - dependency-name: "core" + - dependency-name: "data_api" + - dependency-name: "data_client" + - dependency-name: "data_inmemory" + - dependency-name: "data_repository" + - dependency-name: "http_client" + - dependency-name: "kv_storage_service" + - dependency-name: "kv_storage_shared_preferences" + - dependency-name: "ui_kit" diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 76d9c2b..fb0560f 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,4 +1,4 @@ -name: deploy +name: cd # Run this workflow when a new release is published on: @@ -11,7 +11,7 @@ jobs: steps: # 1. Checkout the repository code - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 # 2. Setup Flutter SDK - name: Setup Flutter @@ -26,11 +26,11 @@ jobs: # 4. Build the Flutter web app - name: Build Web App - run: flutter build web --release --base-href /ht-dashboard/ + run: flutter build web --release --base-href /flutter-news-app-web-dashboard-full-source-code/ # 5. Deploy the built app to GitHub Pages - name: Deploy - uses: peaceiris/actions-gh-pages@v3 + uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./build/web \ No newline at end of file diff --git a/README.md b/README.md index 1dd4603..c8620c2 100644 --- a/README.md +++ b/README.md @@ -1,89 +1,108 @@ -# 📊✨ ht_dashboard +
+Flutter News App Dashboard Logo -![coverage: percentage](https://img.shields.io/badge/coverage-XX-green) -[![Demo: Live](https://img.shields.io/badge/Demo-Live-orange)](https://headlines-toolkit.github.io/ht-dashboard/) -[![style: very good analysis](https://img.shields.io/badge/style-very_good_analysis-B22C89.svg)](https://pub.dev/packages/very_good_analysis) -[![License: PolyForm Free Trial](https://img.shields.io/badge/License-PolyForm%20Free%20Trial-blue)](https://polyformproject.org/licenses/free-trial/1.0.0) +# Flutter News App - Web Dashboard Full Source Code -`ht_dashboard` is a Flutter web application designed as a comprehensive content management and administration interface for the [Headlines Toolkit](https://github.com/headlines-toolkit) ecosystem. It provides a powerful, intuitive platform for managing news content, application configurations, and user-related settings, complementing the [mobile app](https://github.com/headlines-toolkit/ht-main) and the [backend service](https://github.com/headlines-toolkit/ht-api). +

+coverage: percentage +Demo: Live +DOCS READ +License: Buy +

+
-## ⭐ Features & Capabilities +This is a complete and fully-functional Flutter web application for comprehensive content management and administration. It is a key component of the [**flutter news app full source code toolkit**](https://github.com/flutter-news-app-full-source-code), an ecosystem that also includes a dart frog [backend API](https://github.com/flutter-news-app-full-source-code/flutter-news-app-api-server-full-source-code) and a [mobile client](https://github.com/flutter-news-app-full-source-code/flutter-news-app-mobile-client-full-source-code). -`ht_dashboard` offers a robust set of tools for efficient administration: +## ⭐ Everything You Get, Ready to Go + +This dashboard comes packed with all the features you need to manage a professional news application. #### 📰 **Comprehensive Content Management** -Effortlessly manage all aspects of your news content, including: -* **Headlines:** Create, edit, and delete news articles. -* **Categories:** Organize and define news categories. +Effortlessly manage all aspects of your news content with full CRUD (Create, Read, Update, Delete) capabilities: +* **Headlines:** Create, edit, and publish news articles. +* **Topics:** Organize and define news topics. * **Sources:** Maintain and update news sources. -* **Benefit for you:** Centralized control over your content, ensuring accuracy and consistency across your news platform. ✍️ +> **Your Advantage:** You get a powerful, centralized system to control your content, ensuring accuracy and consistency across your news platform. ✍️ #### ⚙️ **Dynamic Application Configuration** -Control the behavior and appearance of the `ht_main` mobile application remotely: -* **User Preference Limits:** Set limits for followed items and saved headlines - based on user roles (Guest, Authenticated, Premium). -* **Ad Settings:** Configure ad frequency and placement intervals for - different user tiers. -* **In-App Prompts:** Manage the display frequency of account-related - calls-to-action. -* **Operational Status (Kill Switch):** Remotely enable maintenance mode or - disable the app. -* **Force Update:** Mandate or suggest app updates to users. -* **Benefit for you:** Granular control over app features and monetization - strategies without requiring app store updates. 🚀 - -#### 📊 **Intuitive User Interface** -Built with Flutter, the dashboard provides a responsive and user-friendly -experience across various web browsers and screen sizes. -* **User-Friendly Error Handling:** Displays clear, localized error messages for a smooth and understandable user experience when issues arise. -* **Benefit for you:** A modern, maintainable, and visually appealing - interface for your administrative tasks. ✨ +Control the behavior and appearance of the mobile application remotely: +* **User Preference Limits:** Set limits for followed items and saved headlines based on user roles (Guest, Authenticated, Premium). +* **Ad Settings:** Configure ad frequency and placement intervals for different user tiers. +* **In-App Prompts:** Manage the display frequency of account-related calls-to-action. +* **Operational Status:** Remotely enable maintenance mode or suggest app updates to users. +> **Your Advantage:** Granular control over app features and monetization strategies without requiring app store updates. 🚀 + +#### 📊 **Dashboard Analytics** +Get a quick overview of your content ecosystem with key statistics: +* **Content Counts:** View the total number of headlines, topics, and sources at a glance. +> **Your Advantage:** Instantly understand the scale of your content operation. 📈 + +#### 🔐 **Robust User Authentication** +Secure and flexible authentication flows are built-in for administrators and publishers using Email + Code (Passwordless) Sign-In. +> **Your Advantage:** All the complex security and user management for your administrative team is already done for you. ✅ + +#### 🖥️ **Responsive Web UI** +Built with `flutter_adaptive_scaffold`, the dashboard offers a clean, responsive interface that looks great on any screen size. +> **Your Advantage:** Deliver a consistent and optimized administrative experience on desktops, tablets, and even mobile browsers. ↔️ #### 🏗️ **Clean & Modern Architecture** Developed with best practices for a maintainable and scalable codebase: * **Flutter & Dart:** Cutting-edge web development. * **BLoC Pattern:** Predictable and robust state management. * **GoRouter:** Well-structured and powerful navigation. -* **Adaptive UI:** Responsive layouts using `flutter_adaptive_scaffold` for - optimal experience on different screen sizes. -* **Benefit for you:** An easy-to-understand, extendable, and testable - foundation for your project. 📈 +> **Your Advantage:** The dashboard is built on a clean, modern architecture that's easy to understand and maintain. It's solid and built to last. 📈 + +#### ⚙️ **Flexible Environment Configuration** +Easily switch between development (in-memory data or local API) and production environments with a simple code change. This empowers rapid prototyping, robust testing, and seamless deployment. +> **Your Advantage:** A flexible setup that speeds up your development cycle and makes deployment simple. 🚀 #### 🌍 **Localization Ready** -Fully internationalized with working English and Arabic localizations (`.arb` files). -* **Benefit for you:** Easily adapt your dashboard for a global team. 🌐 +Fully internationalized with working English and Arabic localizations (`.arb` files). Adding more languages is straightforward. +> **Your Advantage:** Easily adapt your dashboard for a global team. 🌐 --- -## 🔑 Access and Licensing +## 🔑 License: Source-Available with a Free Trial -`ht_dashboard` is source-available as part of the Headlines Toolkit ecosystem. +Get started for free and purchase when you're ready to launch! -To acquire a commercial license for building unlimited news applications, please visit -the [Headlines Toolkit GitHub organization page](https://github.com/headlines-toolkit) -for more details. +* **TRY IT:** Download and explore the full source code under the polyForm free trial [license](LICENSE). Perfect for evaluation. +* **BUY IT:** Get an unlimited commercial lifetime license with a **one-time payment**. No subscriptions! +* **GET YOURS:** [**Purchase via GitHub Sponsors**](https://github.com/sponsors/flutter-news-app-full-source-code). +> *

Note: The single purchase provides a comprehensive commercial license covering every repository within the [Flutter News App - Full Source Code Toolkit](https://github.com/flutter-news-app-full-source-code) organization. No separate purchases are needed for the API or mobile client.

* --- -## 🚀 Getting Started +## 🚀 Getting Started & Running Locally 1. **Ensure Flutter is installed.** (See [Flutter documentation](https://flutter.dev/docs/get-started/install)) 2. **Clone the repository:** ```bash - git clone https://github.com/headlines-toolkit/ht-dashboard.git - cd ht-dashboard + git clone https://github.com/flutter-news-app-full-source-code/flutter-news-app-web-dashboard-full-source-code.git + cd flutter-news-app-web-dashboard-full-source-code ``` 3. **Get dependencies:** ```bash flutter pub get ``` -4. **Run the app for web:** +4. **Run the app:** + + To run the app, first select your desired environment in `lib/main.dart`: + + ```dart + // lib/main.dart + + // Use `AppEnvironment.demo` to run with in-memory data (no API needed). + // Use `AppEnvironment.development` to connect to a local backend API. + // Use `AppEnvironment.production` to connect to a live backend API. + const appEnvironment = AppEnvironment.demo; + ``` + + Then, run the app from your terminal: ```bash flutter run -d chrome - # Or to run on a web server (e.g., for CORS testing with ht_api) - # flutter run -d web-server --web-hostname 0.0.0.0 --web-port 3000 ``` - *(Note: For full functionality, ensure the `ht_api` backend service is running and accessible. If running `ht_api` locally, ensure its `CORS_ALLOWED_ORIGIN` environment variable is configured to allow requests from the dashboard's origin, e.g., `http://localhost:3000` if using the web-server option.)* + *(Note: For `development/production` environment, ensure the [backend service](https://github.com/flutter-news-app-full-source-code/flutter-news-app-api-server-full-source-code) is running.)* --- @@ -94,5 +113,3 @@ This project aims for high test coverage to ensure quality and reliability. * Run tests with: ```bash flutter test - ``` - *(Note: Ensure `very_good_cli` is activated: `dart pub global activate very_good_cli`)* diff --git a/lib/app/bloc/app_bloc.dart b/lib/app/bloc/app_bloc.dart index b04b137..bf43a96 100644 --- a/lib/app/bloc/app_bloc.dart +++ b/lib/app/bloc/app_bloc.dart @@ -2,12 +2,13 @@ import 'dart:async'; +import 'package:auth_repository/auth_repository.dart'; import 'package:bloc/bloc.dart'; +import 'package:core/core.dart'; +import 'package:data_repository/data_repository.dart'; import 'package:equatable/equatable.dart'; -import 'package:ht_auth_repository/ht_auth_repository.dart'; -import 'package:ht_dashboard/app/config/config.dart' as local_config; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/app/config/config.dart' + as local_config; import 'package:logging/logging.dart'; part 'app_event.dart'; @@ -15,18 +16,16 @@ part 'app_state.dart'; class AppBloc extends Bloc { AppBloc({ - required HtAuthRepository authenticationRepository, - required HtDataRepository userAppSettingsRepository, - required HtDataRepository appConfigRepository, + required AuthRepository authenticationRepository, + required DataRepository userAppSettingsRepository, + required DataRepository appConfigRepository, required local_config.AppEnvironment environment, Logger? logger, }) : _authenticationRepository = authenticationRepository, _userAppSettingsRepository = userAppSettingsRepository, _appConfigRepository = appConfigRepository, _logger = logger ?? Logger('AppBloc'), - super( - AppState(environment: environment), - ) { + super(AppState(environment: environment)) { on(_onAppUserChanged); on(_onLogoutRequested); on(_onAppUserAppSettingsChanged); @@ -36,9 +35,9 @@ class AppBloc extends Bloc { ); } - final HtAuthRepository _authenticationRepository; - final HtDataRepository _userAppSettingsRepository; - final HtDataRepository _appConfigRepository; + final AuthRepository _authenticationRepository; + final DataRepository _userAppSettingsRepository; + final DataRepository _appConfigRepository; final Logger _logger; late final StreamSubscription _userSubscription; @@ -97,7 +96,7 @@ class AppBloc extends Bloc { ); await _userAppSettingsRepository.create(item: defaultSettings); emit(state.copyWith(userAppSettings: defaultSettings)); - } on HtHttpException catch (e, s) { + } on HttpException catch (e, s) { // Handle HTTP exceptions during settings load _logger.severe( 'Error loading user app settings for user ${user.id}: ${e.message}', diff --git a/lib/app/config/app_config.dart b/lib/app/config/app_config.dart index 289f1e4..1c1f793 100644 --- a/lib/app/config/app_config.dart +++ b/lib/app/config/app_config.dart @@ -1,20 +1,15 @@ -import 'package:ht_dashboard/app/config/app_environment.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/app/config/app_environment.dart'; class AppConfig { - const AppConfig({ - required this.environment, - required this.baseUrl, - }); + const AppConfig({required this.environment, required this.baseUrl}); factory AppConfig.production() => const AppConfig( environment: AppEnvironment.production, baseUrl: 'http://api.yourproductiondomain.com', ); - factory AppConfig.demo() => const AppConfig( - environment: AppEnvironment.demo, - baseUrl: '', - ); + factory AppConfig.demo() => + const AppConfig(environment: AppEnvironment.demo, baseUrl: ''); factory AppConfig.development() => const AppConfig( environment: AppEnvironment.development, diff --git a/lib/app/view/app.dart b/lib/app/view/app.dart index 9c86a5f..b270aa7 100644 --- a/lib/app/view/app.dart +++ b/lib/app/view/app.dart @@ -1,122 +1,121 @@ // // ignore_for_file: deprecated_member_use +import 'package:auth_repository/auth_repository.dart'; +import 'package:core/core.dart' hide AppStatus; +// Import for app_theme.dart +import 'package:data_repository/data_repository.dart'; import 'package:flex_color_scheme/flex_color_scheme.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/app/bloc/app_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/app/config/app_environment.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/app_configuration/bloc/app_configuration_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/authentication/bloc/authentication_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/bloc/content_management_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/dashboard/bloc/dashboard_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/app_localizations.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/router/router.dart'; import 'package:go_router/go_router.dart'; -import 'package:ht_auth_repository/ht_auth_repository.dart'; -import 'package:ht_dashboard/app/bloc/app_bloc.dart'; -import 'package:ht_dashboard/app/config/app_environment.dart'; -import 'package:ht_dashboard/app_configuration/bloc/app_configuration_bloc.dart'; -import 'package:ht_dashboard/authentication/bloc/authentication_bloc.dart'; -import 'package:ht_dashboard/content_management/bloc/content_management_bloc.dart'; -import 'package:ht_dashboard/dashboard/bloc/dashboard_bloc.dart'; -import 'package:ht_dashboard/l10n/app_localizations.dart'; -import 'package:ht_dashboard/router/router.dart'; -// Import for app_theme.dart -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_kv_storage_service/ht_kv_storage_service.dart'; -import 'package:ht_shared/ht_shared.dart' hide AppStatus; -import 'package:ht_ui_kit/ht_ui_kit.dart'; +import 'package:kv_storage_service/kv_storage_service.dart'; import 'package:logging/logging.dart'; +import 'package:ui_kit/ui_kit.dart'; class App extends StatelessWidget { const App({ - required HtAuthRepository htAuthenticationRepository, - required HtDataRepository htHeadlinesRepository, - required HtDataRepository htTopicsRepository, - required HtDataRepository htCountriesRepository, - required HtDataRepository htSourcesRepository, - required HtDataRepository htUserAppSettingsRepository, - required HtDataRepository - htUserContentPreferencesRepository, - required HtDataRepository htRemoteConfigRepository, - required HtDataRepository htDashboardSummaryRepository, - required HtKVStorageService kvStorageService, + required AuthRepository authenticationRepository, + required DataRepository headlinesRepository, + required DataRepository topicsRepository, + required DataRepository countriesRepository, + required DataRepository sourcesRepository, + required DataRepository userAppSettingsRepository, + required DataRepository + userContentPreferencesRepository, + required DataRepository remoteConfigRepository, + required DataRepository dashboardSummaryRepository, + required KVStorageService storageService, required AppEnvironment environment, super.key, - }) : _htAuthenticationRepository = htAuthenticationRepository, - _htHeadlinesRepository = htHeadlinesRepository, - _htTopicsRepository = htTopicsRepository, - _htCountriesRepository = htCountriesRepository, - _htSourcesRepository = htSourcesRepository, - _htUserAppSettingsRepository = htUserAppSettingsRepository, - _htUserContentPreferencesRepository = htUserContentPreferencesRepository, - _htRemoteConfigRepository = htRemoteConfigRepository, - _kvStorageService = kvStorageService, - _htDashboardSummaryRepository = htDashboardSummaryRepository, + }) : _authenticationRepository = authenticationRepository, + _headlinesRepository = headlinesRepository, + _topicsRepository = topicsRepository, + _countriesRepository = countriesRepository, + _sourcesRepository = sourcesRepository, + _userAppSettingsRepository = userAppSettingsRepository, + _userContentPreferencesRepository = userContentPreferencesRepository, + _remoteConfigRepository = remoteConfigRepository, + _kvStorageService = storageService, + _dashboardSummaryRepository = dashboardSummaryRepository, _environment = environment; - final HtAuthRepository _htAuthenticationRepository; - final HtDataRepository _htHeadlinesRepository; - final HtDataRepository _htTopicsRepository; - final HtDataRepository _htCountriesRepository; - final HtDataRepository _htSourcesRepository; - final HtDataRepository _htUserAppSettingsRepository; - final HtDataRepository - _htUserContentPreferencesRepository; - final HtDataRepository _htRemoteConfigRepository; - final HtDataRepository _htDashboardSummaryRepository; - final HtKVStorageService _kvStorageService; + final AuthRepository _authenticationRepository; + final DataRepository _headlinesRepository; + final DataRepository _topicsRepository; + final DataRepository _countriesRepository; + final DataRepository _sourcesRepository; + final DataRepository _userAppSettingsRepository; + final DataRepository + _userContentPreferencesRepository; + final DataRepository _remoteConfigRepository; + final DataRepository _dashboardSummaryRepository; + final KVStorageService _kvStorageService; final AppEnvironment _environment; @override Widget build(BuildContext context) { return MultiRepositoryProvider( providers: [ - RepositoryProvider.value(value: _htAuthenticationRepository), - RepositoryProvider.value(value: _htHeadlinesRepository), - RepositoryProvider.value(value: _htTopicsRepository), - RepositoryProvider.value(value: _htCountriesRepository), - RepositoryProvider.value(value: _htSourcesRepository), - RepositoryProvider.value(value: _htUserAppSettingsRepository), - RepositoryProvider.value(value: _htUserContentPreferencesRepository), - RepositoryProvider.value(value: _htRemoteConfigRepository), - RepositoryProvider.value(value: _htDashboardSummaryRepository), + RepositoryProvider.value(value: _authenticationRepository), + RepositoryProvider.value(value: _headlinesRepository), + RepositoryProvider.value(value: _topicsRepository), + RepositoryProvider.value(value: _countriesRepository), + RepositoryProvider.value(value: _sourcesRepository), + RepositoryProvider.value(value: _userAppSettingsRepository), + RepositoryProvider.value(value: _userContentPreferencesRepository), + RepositoryProvider.value(value: _remoteConfigRepository), + RepositoryProvider.value(value: _dashboardSummaryRepository), RepositoryProvider.value(value: _kvStorageService), ], child: MultiBlocProvider( providers: [ BlocProvider( create: (context) => AppBloc( - authenticationRepository: context.read(), + authenticationRepository: context.read(), userAppSettingsRepository: context - .read>(), - appConfigRepository: context - .read>(), + .read>(), + appConfigRepository: context.read>(), environment: _environment, logger: Logger('AppBloc'), ), ), BlocProvider( create: (context) => AuthenticationBloc( - authenticationRepository: context.read(), + authenticationRepository: context.read(), ), ), BlocProvider( create: (context) => AppConfigurationBloc( remoteConfigRepository: context - .read>(), + .read>(), ), ), BlocProvider( create: (context) => ContentManagementBloc( - headlinesRepository: context.read>(), - topicsRepository: context.read>(), - sourcesRepository: context.read>(), + headlinesRepository: context.read>(), + topicsRepository: context.read>(), + sourcesRepository: context.read>(), ), ), BlocProvider( create: (context) => DashboardBloc( dashboardSummaryRepository: context - .read>(), - headlinesRepository: context.read>(), + .read>(), + headlinesRepository: context.read>(), ), ), ], child: _AppView( - htAuthenticationRepository: _htAuthenticationRepository, + authenticationRepository: _authenticationRepository, environment: _environment, ), ), @@ -127,11 +126,11 @@ class App extends StatelessWidget { class _AppView extends StatefulWidget { /// {@macro app_view} const _AppView({ - required this.htAuthenticationRepository, + required this.authenticationRepository, required this.environment, }); - final HtAuthRepository htAuthenticationRepository; + final AuthRepository authenticationRepository; final AppEnvironment environment; @override @@ -149,7 +148,7 @@ class _AppViewState extends State<_AppView> { _statusNotifier = ValueNotifier(appBloc.state.status); _router = createRouter( authStatusNotifier: _statusNotifier, - htAuthenticationRepository: widget.htAuthenticationRepository, + authenticationRepository: widget.authenticationRepository, environment: widget.environment, ); } @@ -210,10 +209,10 @@ class _AppViewState extends State<_AppView> { debugShowCheckedModeBanner: false, routerConfig: _router, localizationsDelegates: const [ - HtUiKitLocalizations.delegate, + UiKitLocalizations.delegate, ...AppLocalizations.localizationsDelegates, ], - supportedLocales: HtUiKitLocalizations.supportedLocales, + supportedLocales: UiKitLocalizations.supportedLocales, theme: baseTheme == AppBaseTheme.dark ? darkThemeData : lightThemeData, diff --git a/lib/app/view/app_shell.dart b/lib/app/view/app_shell.dart index 5945047..ac054f2 100644 --- a/lib/app/view/app_shell.dart +++ b/lib/app/view/app_shell.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_adaptive_scaffold/flutter_adaptive_scaffold.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/app/bloc/app_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/router/routes.dart'; import 'package:go_router/go_router.dart'; -import 'package:ht_dashboard/app/bloc/app_bloc.dart'; -import 'package:ht_dashboard/l10n/l10n.dart'; -import 'package:ht_dashboard/router/routes.dart'; -import 'package:ht_ui_kit/ht_ui_kit.dart'; +import 'package:ui_kit/ui_kit.dart'; /// A responsive scaffold shell for the main application sections. /// diff --git a/lib/app_configuration/bloc/app_configuration_bloc.dart b/lib/app_configuration/bloc/app_configuration_bloc.dart index 5a70521..1618ab1 100644 --- a/lib/app_configuration/bloc/app_configuration_bloc.dart +++ b/lib/app_configuration/bloc/app_configuration_bloc.dart @@ -1,7 +1,7 @@ import 'package:bloc/bloc.dart'; +import 'package:core/core.dart'; +import 'package:data_repository/data_repository.dart'; import 'package:equatable/equatable.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; part 'app_configuration_event.dart'; part 'app_configuration_state.dart'; @@ -9,18 +9,16 @@ part 'app_configuration_state.dart'; class AppConfigurationBloc extends Bloc { AppConfigurationBloc({ - required HtDataRepository remoteConfigRepository, + required DataRepository remoteConfigRepository, }) : _remoteConfigRepository = remoteConfigRepository, - super( - const AppConfigurationState(), - ) { + super(const AppConfigurationState()) { on(_onAppConfigurationLoaded); on(_onAppConfigurationUpdated); on(_onAppConfigurationFieldChanged); on(_onAppConfigurationDiscarded); } - final HtDataRepository _remoteConfigRepository; + final DataRepository _remoteConfigRepository; Future _onAppConfigurationLoaded( AppConfigurationLoaded event, @@ -41,12 +39,9 @@ class AppConfigurationBloc true, // Clear any previous success snackbar flag ), ); - } on HtHttpException catch (e) { + } on HttpException catch (e) { emit( - state.copyWith( - status: AppConfigurationStatus.failure, - exception: e, - ), + state.copyWith(status: AppConfigurationStatus.failure, exception: e), ); } catch (e) { emit( @@ -77,12 +72,9 @@ class AppConfigurationBloc showSaveSuccess: true, // Set flag to show success snackbar ), ); - } on HtHttpException catch (e) { + } on HttpException catch (e) { emit( - state.copyWith( - status: AppConfigurationStatus.failure, - exception: e, - ), + state.copyWith(status: AppConfigurationStatus.failure, exception: e), ); } catch (e) { emit( diff --git a/lib/app_configuration/bloc/app_configuration_state.dart b/lib/app_configuration/bloc/app_configuration_state.dart index c3cbe49..e40cd77 100644 --- a/lib/app_configuration/bloc/app_configuration_state.dart +++ b/lib/app_configuration/bloc/app_configuration_state.dart @@ -39,7 +39,7 @@ class AppConfigurationState extends Equatable { final RemoteConfig? originalRemoteConfig; /// An error exception if an operation failed. - final HtHttpException? exception; + final HttpException? exception; /// Indicates if there are unsaved changes to the configuration. final bool isDirty; @@ -52,7 +52,7 @@ class AppConfigurationState extends Equatable { AppConfigurationStatus? status, RemoteConfig? remoteConfig, RemoteConfig? originalRemoteConfig, - HtHttpException? exception, + HttpException? exception, bool? isDirty, bool clearException = false, bool? showSaveSuccess, diff --git a/lib/app_configuration/view/app_configuration_page.dart b/lib/app_configuration/view/app_configuration_page.dart index 488d7c1..2f15050 100644 --- a/lib/app_configuration/view/app_configuration_page.dart +++ b/lib/app_configuration/view/app_configuration_page.dart @@ -1,10 +1,10 @@ +import 'package:core/core.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:ht_dashboard/app_configuration/bloc/app_configuration_bloc.dart'; -import 'package:ht_dashboard/l10n/app_localizations.dart'; -import 'package:ht_dashboard/l10n/l10n.dart'; -import 'package:ht_shared/ht_shared.dart'; -import 'package:ht_ui_kit/ht_ui_kit.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/app_configuration/bloc/app_configuration_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/app_localizations.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart'; +import 'package:ui_kit/ui_kit.dart'; /// {@template app_configuration_page} /// A page for managing the application's remote configuration. @@ -176,9 +176,7 @@ class _AppConfigurationPageState extends State childrenPadding: const EdgeInsets.symmetric( horizontal: AppSpacing.xxl, ), - children: [ - _buildAdConfigSection(context, remoteConfig), - ], + children: [_buildAdConfigSection(context, remoteConfig)], ), ], ), @@ -316,9 +314,7 @@ class _AppConfigurationPageState extends State remoteConfig: remoteConfig, onConfigChanged: (newConfig) { context.read().add( - AppConfigurationFieldChanged( - remoteConfig: newConfig, - ), + AppConfigurationFieldChanged(remoteConfig: newConfig), ); }, buildIntField: _buildIntField, @@ -336,9 +332,7 @@ class _AppConfigurationPageState extends State remoteConfig: remoteConfig, onConfigChanged: (newConfig) { context.read().add( - AppConfigurationFieldChanged( - remoteConfig: newConfig, - ), + AppConfigurationFieldChanged(remoteConfig: newConfig), ); }, buildIntField: _buildIntField, @@ -356,9 +350,7 @@ class _AppConfigurationPageState extends State remoteConfig: remoteConfig, onConfigChanged: (newConfig) { context.read().add( - AppConfigurationFieldChanged( - remoteConfig: newConfig, - ), + AppConfigurationFieldChanged(remoteConfig: newConfig), ); }, buildIntField: _buildIntField, @@ -395,9 +387,7 @@ class _AppConfigurationPageState extends State remoteConfig: remoteConfig, onConfigChanged: (newConfig) { context.read().add( - AppConfigurationFieldChanged( - remoteConfig: newConfig, - ), + AppConfigurationFieldChanged(remoteConfig: newConfig), ); }, buildIntField: _buildIntField, @@ -415,9 +405,7 @@ class _AppConfigurationPageState extends State remoteConfig: remoteConfig, onConfigChanged: (newConfig) { context.read().add( - AppConfigurationFieldChanged( - remoteConfig: newConfig, - ), + AppConfigurationFieldChanged(remoteConfig: newConfig), ); }, buildIntField: _buildIntField, @@ -435,9 +423,7 @@ class _AppConfigurationPageState extends State remoteConfig: remoteConfig, onConfigChanged: (newConfig) { context.read().add( - AppConfigurationFieldChanged( - remoteConfig: newConfig, - ), + AppConfigurationFieldChanged(remoteConfig: newConfig), ); }, buildIntField: _buildIntField, @@ -474,9 +460,7 @@ class _AppConfigurationPageState extends State remoteConfig: remoteConfig, onConfigChanged: (newConfig) { context.read().add( - AppConfigurationFieldChanged( - remoteConfig: newConfig, - ), + AppConfigurationFieldChanged(remoteConfig: newConfig), ); }, buildIntField: _buildIntField, @@ -494,9 +478,7 @@ class _AppConfigurationPageState extends State remoteConfig: remoteConfig, onConfigChanged: (newConfig) { context.read().add( - AppConfigurationFieldChanged( - remoteConfig: newConfig, - ), + AppConfigurationFieldChanged(remoteConfig: newConfig), ); }, buildIntField: _buildIntField, @@ -659,10 +641,7 @@ class _AppConfigurationPageState extends State child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - label, - style: Theme.of(context).textTheme.titleMedium, - ), + Text(label, style: Theme.of(context).textTheme.titleMedium), const SizedBox(height: AppSpacing.xs), Text( description, @@ -704,10 +683,7 @@ class _AppConfigurationPageState extends State child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - label, - style: Theme.of(context).textTheme.titleMedium, - ), + Text(label, style: Theme.of(context).textTheme.titleMedium), const SizedBox(height: AppSpacing.xs), Text( description, @@ -1326,9 +1302,7 @@ class _AccountActionConfigFormState extends State<_AccountActionConfigForm> { return widget.buildIntField( context, label: '$localizedActionType ${l10n.daysSuffix}', - description: l10n.daysBetweenPromptDescription( - localizedActionType, - ), + description: l10n.daysBetweenPromptDescription(localizedActionType), value: _getDaysMap(accountActionConfig)[actionType] ?? 0, onChanged: (value) { final currentMap = Map.from( diff --git a/lib/authentication/bloc/authentication_bloc.dart b/lib/authentication/bloc/authentication_bloc.dart index 5a25421..aeb92bc 100644 --- a/lib/authentication/bloc/authentication_bloc.dart +++ b/lib/authentication/bloc/authentication_bloc.dart @@ -1,13 +1,12 @@ import 'dart:async'; +import 'package:auth_repository/auth_repository.dart'; import 'package:bloc/bloc.dart'; -import 'package:equatable/equatable.dart'; -import 'package:ht_auth_repository/ht_auth_repository.dart'; -import 'package:ht_shared/ht_shared.dart' +import 'package:core/core.dart' show AuthenticationException, ForbiddenException, - HtHttpException, + HttpException, InvalidInputException, NetworkException, NotFoundException, @@ -16,6 +15,7 @@ import 'package:ht_shared/ht_shared.dart' UnauthorizedException, UnknownException, User; +import 'package:equatable/equatable.dart'; part 'authentication_event.dart'; part 'authentication_state.dart'; @@ -26,7 +26,7 @@ part 'authentication_state.dart'; class AuthenticationBloc extends Bloc { /// {@macro authentication_bloc} - AuthenticationBloc({required HtAuthRepository authenticationRepository}) + AuthenticationBloc({required AuthRepository authenticationRepository}) : _authenticationRepository = authenticationRepository, super(const AuthenticationState()) { // Listen to authentication state changes from the repository @@ -42,7 +42,7 @@ class AuthenticationBloc on(_onAuthenticationSignOutRequested); } - final HtAuthRepository _authenticationRepository; + final AuthRepository _authenticationRepository; late final StreamSubscription _userAuthSubscription; /// Handles [_AuthenticationStatusChanged] events. @@ -85,55 +85,20 @@ class AuthenticationBloc ), ); } on InvalidInputException catch (e) { - emit( - state.copyWith( - status: AuthenticationStatus.failure, - exception: e, - ), - ); + emit(state.copyWith(status: AuthenticationStatus.failure, exception: e)); } on UnauthorizedException catch (e) { - emit( - state.copyWith( - status: AuthenticationStatus.failure, - exception: e, - ), - ); + emit(state.copyWith(status: AuthenticationStatus.failure, exception: e)); } on ForbiddenException catch (e) { - emit( - state.copyWith( - status: AuthenticationStatus.failure, - exception: e, - ), - ); + emit(state.copyWith(status: AuthenticationStatus.failure, exception: e)); } on NetworkException catch (e) { - emit( - state.copyWith( - status: AuthenticationStatus.failure, - exception: e, - ), - ); + emit(state.copyWith(status: AuthenticationStatus.failure, exception: e)); } on ServerException catch (e) { - emit( - state.copyWith( - status: AuthenticationStatus.failure, - exception: e, - ), - ); + emit(state.copyWith(status: AuthenticationStatus.failure, exception: e)); } on OperationFailedException catch (e) { - emit( - state.copyWith( - status: AuthenticationStatus.failure, - exception: e, - ), - ); - } on HtHttpException catch (e) { - // Catch any other HtHttpException subtypes - emit( - state.copyWith( - status: AuthenticationStatus.failure, - exception: e, - ), - ); + emit(state.copyWith(status: AuthenticationStatus.failure, exception: e)); + } on HttpException catch (e) { + // Catch any other HttpException subtypes + emit(state.copyWith(status: AuthenticationStatus.failure, exception: e)); } catch (e) { // Catch any other unexpected errors emit( @@ -161,55 +126,20 @@ class AuthenticationBloc // On success, the _AuthenticationStatusChanged listener will handle // emitting AuthenticationAuthenticated. } on InvalidInputException catch (e) { - emit( - state.copyWith( - status: AuthenticationStatus.failure, - exception: e, - ), - ); + emit(state.copyWith(status: AuthenticationStatus.failure, exception: e)); } on AuthenticationException catch (e) { - emit( - state.copyWith( - status: AuthenticationStatus.failure, - exception: e, - ), - ); + emit(state.copyWith(status: AuthenticationStatus.failure, exception: e)); } on NotFoundException catch (e) { - emit( - state.copyWith( - status: AuthenticationStatus.failure, - exception: e, - ), - ); + emit(state.copyWith(status: AuthenticationStatus.failure, exception: e)); } on NetworkException catch (e) { - emit( - state.copyWith( - status: AuthenticationStatus.failure, - exception: e, - ), - ); + emit(state.copyWith(status: AuthenticationStatus.failure, exception: e)); } on ServerException catch (e) { - emit( - state.copyWith( - status: AuthenticationStatus.failure, - exception: e, - ), - ); + emit(state.copyWith(status: AuthenticationStatus.failure, exception: e)); } on OperationFailedException catch (e) { - emit( - state.copyWith( - status: AuthenticationStatus.failure, - exception: e, - ), - ); - } on HtHttpException catch (e) { - // Catch any other HtHttpException subtypes - emit( - state.copyWith( - status: AuthenticationStatus.failure, - exception: e, - ), - ); + emit(state.copyWith(status: AuthenticationStatus.failure, exception: e)); + } on HttpException catch (e) { + // Catch any other HttpException subtypes + emit(state.copyWith(status: AuthenticationStatus.failure, exception: e)); } catch (e) { // Catch any other unexpected errors emit( @@ -233,34 +163,14 @@ class AuthenticationBloc // On success, the _AuthenticationStatusChanged listener will handle // emitting AuthenticationUnauthenticated. } on NetworkException catch (e) { - emit( - state.copyWith( - status: AuthenticationStatus.failure, - exception: e, - ), - ); + emit(state.copyWith(status: AuthenticationStatus.failure, exception: e)); } on ServerException catch (e) { - emit( - state.copyWith( - status: AuthenticationStatus.failure, - exception: e, - ), - ); + emit(state.copyWith(status: AuthenticationStatus.failure, exception: e)); } on OperationFailedException catch (e) { - emit( - state.copyWith( - status: AuthenticationStatus.failure, - exception: e, - ), - ); - } on HtHttpException catch (e) { - // Catch any other HtHttpException subtypes - emit( - state.copyWith( - status: AuthenticationStatus.failure, - exception: e, - ), - ); + emit(state.copyWith(status: AuthenticationStatus.failure, exception: e)); + } on HttpException catch (e) { + // Catch any other HttpException subtypes + emit(state.copyWith(status: AuthenticationStatus.failure, exception: e)); } catch (e) { emit( state.copyWith( diff --git a/lib/authentication/bloc/authentication_state.dart b/lib/authentication/bloc/authentication_state.dart index b12250e..14449f1 100644 --- a/lib/authentication/bloc/authentication_state.dart +++ b/lib/authentication/bloc/authentication_state.dart @@ -48,7 +48,7 @@ final class AuthenticationState extends Equatable { final String? email; /// The error describing an authentication failure, if any. - final HtHttpException? exception; + final HttpException? exception; @override List get props => [status, user, email, exception]; @@ -59,7 +59,7 @@ final class AuthenticationState extends Equatable { AuthenticationStatus? status, User? user, String? email, - HtHttpException? exception, + HttpException? exception, }) { return AuthenticationState( status: status ?? this.status, diff --git a/lib/authentication/view/authentication_page.dart b/lib/authentication/view/authentication_page.dart index da4762c..071d713 100644 --- a/lib/authentication/view/authentication_page.dart +++ b/lib/authentication/view/authentication_page.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/authentication/bloc/authentication_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/router/routes.dart'; import 'package:go_router/go_router.dart'; -import 'package:ht_dashboard/authentication/bloc/authentication_bloc.dart'; -import 'package:ht_dashboard/l10n/l10n.dart'; -import 'package:ht_dashboard/router/routes.dart'; -import 'package:ht_ui_kit/ht_ui_kit.dart'; +import 'package:ui_kit/ui_kit.dart'; /// {@template authentication_page} /// Displays authentication options for the dashboard. @@ -23,10 +23,7 @@ class AuthenticationPage extends StatelessWidget { final colorScheme = Theme.of(context).colorScheme; return Scaffold( - appBar: AppBar( - backgroundColor: Colors.transparent, - elevation: 0, - ), + appBar: AppBar(backgroundColor: Colors.transparent, elevation: 0), body: SafeArea( child: BlocConsumer( // Listener remains crucial for feedback (errors) @@ -65,9 +62,7 @@ class AuthenticationPage extends StatelessWidget { children: [ // --- Icon --- Padding( - padding: const EdgeInsets.only( - bottom: AppSpacing.xl, - ), + padding: const EdgeInsets.only(bottom: AppSpacing.xl), child: Icon( Icons.newspaper, size: AppSpacing.xxl * 2, @@ -98,9 +93,7 @@ class AuthenticationPage extends StatelessWidget { onPressed: isLoading ? null : () { - context.goNamed( - Routes.requestCodeName, - ); + context.goNamed(Routes.requestCodeName); }, label: Text(l10n.authenticationEmailSignInButton), style: ElevatedButton.styleFrom( diff --git a/lib/authentication/view/email_code_verification_page.dart b/lib/authentication/view/email_code_verification_page.dart index 950f52f..1dcf3c2 100644 --- a/lib/authentication/view/email_code_verification_page.dart +++ b/lib/authentication/view/email_code_verification_page.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:ht_dashboard/app/bloc/app_bloc.dart'; -import 'package:ht_dashboard/app/config/config.dart'; -import 'package:ht_dashboard/authentication/bloc/authentication_bloc.dart'; -import 'package:ht_dashboard/l10n/l10n.dart'; -import 'package:ht_ui_kit/ht_ui_kit.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/app/bloc/app_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/app/config/config.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/authentication/bloc/authentication_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart'; +import 'package:ui_kit/ui_kit.dart'; /// {@template email_code_verification_page} /// Page where the user enters the 6-digit code sent to their email diff --git a/lib/authentication/view/request_code_page.dart b/lib/authentication/view/request_code_page.dart index 9777169..84ed468 100644 --- a/lib/authentication/view/request_code_page.dart +++ b/lib/authentication/view/request_code_page.dart @@ -3,13 +3,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/app/bloc/app_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/app/config/config.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/authentication/bloc/authentication_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/router/routes.dart'; import 'package:go_router/go_router.dart'; -import 'package:ht_dashboard/app/bloc/app_bloc.dart'; -import 'package:ht_dashboard/app/config/config.dart'; -import 'package:ht_dashboard/authentication/bloc/authentication_bloc.dart'; -import 'package:ht_dashboard/l10n/l10n.dart'; -import 'package:ht_dashboard/router/routes.dart'; -import 'package:ht_ui_kit/ht_ui_kit.dart'; +import 'package:ui_kit/ui_kit.dart'; /// {@template request_code_page} /// Page for initiating the email code sign-in process. diff --git a/lib/bootstrap.dart b/lib/bootstrap.dart index f9de1ad..efd5dcb 100644 --- a/lib/bootstrap.dart +++ b/lib/bootstrap.dart @@ -1,22 +1,23 @@ +import 'package:auth_api/auth_api.dart'; +import 'package:auth_client/auth_client.dart'; +import 'package:auth_inmemory/auth_inmemory.dart'; +import 'package:auth_repository/auth_repository.dart'; +import 'package:core/core.dart'; +import 'package:data_api/data_api.dart'; +import 'package:data_client/data_client.dart'; +import 'package:data_inmemory/data_inmemory.dart'; +import 'package:data_repository/data_repository.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:ht_auth_api/ht_auth_api.dart'; -import 'package:ht_auth_client/ht_auth_client.dart'; -import 'package:ht_auth_inmemory/ht_auth_inmemory.dart'; -import 'package:ht_auth_repository/ht_auth_repository.dart'; -import 'package:ht_dashboard/app/app.dart'; -import 'package:ht_dashboard/app/config/config.dart' as app_config; -import 'package:ht_dashboard/bloc_observer.dart'; -import 'package:ht_data_api/ht_data_api.dart'; -import 'package:ht_data_client/ht_data_client.dart'; -import 'package:ht_data_inmemory/ht_data_inmemory.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_http_client/ht_http_client.dart'; -import 'package:ht_kv_storage_shared_preferences/ht_kv_storage_shared_preferences.dart'; -import 'package:ht_shared/ht_shared.dart'; -import 'package:ht_ui_kit/ht_ui_kit.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/app/app.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/app/config/config.dart' + as app_config; +import 'package:flutter_news_app_web_dashboard_full_source_code/bloc_observer.dart'; +import 'package:http_client/http_client.dart'; +import 'package:kv_storage_shared_preferences/kv_storage_shared_preferences.dart'; import 'package:logging/logging.dart'; import 'package:timeago/timeago.dart' as timeago; +import 'package:ui_kit/ui_kit.dart'; Future bootstrap( app_config.AppConfig appConfig, @@ -28,242 +29,235 @@ Future bootstrap( timeago.setLocaleMessages('en', EnTimeagoMessages()); timeago.setLocaleMessages('ar', ArTimeagoMessages()); - final kvStorage = await HtKvStorageSharedPreferences.getInstance(); + final kvStorage = await KVStorageSharedPreferences.getInstance(); - late final HtAuthClient authClient; - late final HtAuthRepository authenticationRepository; - HtHttpClient? httpClient; + late final AuthClient authClient; + late final AuthRepository authenticationRepository; + HttpClient? httpClient; if (appConfig.environment == app_config.AppEnvironment.demo) { - authClient = HtAuthInmemory( - logger: Logger('HtAuthInmemory'), - ); - authenticationRepository = HtAuthRepository( + authClient = AuthInmemory(logger: Logger('AuthInmemory')); + authenticationRepository = AuthRepository( authClient: authClient, storageService: kvStorage, ); } else { - httpClient = HtHttpClient( + httpClient = HttpClient( baseUrl: appConfig.baseUrl, tokenProvider: () => authenticationRepository.getAuthToken(), ); - authClient = HtAuthApi( - httpClient: httpClient, - logger: Logger('HtAuthApi'), - ); - authenticationRepository = HtAuthRepository( + authClient = AuthApi(httpClient: httpClient, logger: Logger('AuthApi')); + authenticationRepository = AuthRepository( authClient: authClient, storageService: kvStorage, ); } - HtDataClient headlinesClient; - HtDataClient topicsClient; - HtDataClient countriesClient; - HtDataClient sourcesClient; - HtDataClient userContentPreferencesClient; - HtDataClient userAppSettingsClient; - HtDataClient remoteConfigClient; - HtDataClient dashboardSummaryClient; + DataClient headlinesClient; + DataClient topicsClient; + DataClient countriesClient; + DataClient sourcesClient; + DataClient userContentPreferencesClient; + DataClient userAppSettingsClient; + DataClient remoteConfigClient; + DataClient dashboardSummaryClient; if (appConfig.environment == app_config.AppEnvironment.demo) { - headlinesClient = HtDataInMemory( + headlinesClient = DataInMemory( toJson: (i) => i.toJson(), getId: (i) => i.id, initialData: headlinesFixturesData, - logger: Logger('HtDataInMemory'), + logger: Logger('DataInMemory'), ); - topicsClient = HtDataInMemory( + topicsClient = DataInMemory( toJson: (i) => i.toJson(), getId: (i) => i.id, initialData: topicsFixturesData, - logger: Logger('HtDataInMemory'), + logger: Logger('DataInMemory'), ); - countriesClient = HtDataInMemory( + countriesClient = DataInMemory( toJson: (i) => i.toJson(), getId: (i) => i.id, initialData: countriesFixturesData, - logger: Logger('HtDataInMemory'), + logger: Logger('DataInMemory'), ); - sourcesClient = HtDataInMemory( + sourcesClient = DataInMemory( toJson: (i) => i.toJson(), getId: (i) => i.id, initialData: sourcesFixturesData, - logger: Logger('HtDataInMemory'), + logger: Logger('DataInMemory'), ); - userContentPreferencesClient = HtDataInMemory( + userContentPreferencesClient = DataInMemory( toJson: (i) => i.toJson(), getId: (i) => i.id, - logger: Logger('HtDataInMemory'), + logger: Logger('DataInMemory'), ); - userAppSettingsClient = HtDataInMemory( + userAppSettingsClient = DataInMemory( toJson: (i) => i.toJson(), getId: (i) => i.id, - logger: Logger('HtDataInMemory'), + logger: Logger('DataInMemory'), ); - remoteConfigClient = HtDataInMemory( + remoteConfigClient = DataInMemory( toJson: (i) => i.toJson(), getId: (i) => i.id, initialData: remoteConfigsFixturesData, - logger: Logger('HtDataInMemory'), + logger: Logger('DataInMemory'), ); - dashboardSummaryClient = HtDataInMemory( + dashboardSummaryClient = DataInMemory( toJson: (i) => i.toJson(), getId: (i) => i.id, initialData: dashboardSummaryFixturesData, - logger: Logger('HtDataInMemory'), + logger: Logger('DataInMemory'), ); } else if (appConfig.environment == app_config.AppEnvironment.development) { - headlinesClient = HtDataApi( + headlinesClient = DataApi( httpClient: httpClient!, modelName: 'headline', fromJson: Headline.fromJson, toJson: (headline) => headline.toJson(), - logger: Logger('HtDataApi'), + logger: Logger('DataApi'), ); - topicsClient = HtDataApi( + topicsClient = DataApi( httpClient: httpClient, modelName: 'topic', fromJson: Topic.fromJson, toJson: (topic) => topic.toJson(), - logger: Logger('HtDataApi'), + logger: Logger('DataApi'), ); - countriesClient = HtDataApi( + countriesClient = DataApi( httpClient: httpClient, modelName: 'country', fromJson: Country.fromJson, toJson: (country) => country.toJson(), - logger: Logger('HtDataApi'), + logger: Logger('DataApi'), ); - sourcesClient = HtDataApi( + sourcesClient = DataApi( httpClient: httpClient, modelName: 'source', fromJson: Source.fromJson, toJson: (source) => source.toJson(), - logger: Logger('HtDataApi'), + logger: Logger('DataApi'), ); - userContentPreferencesClient = HtDataApi( + userContentPreferencesClient = DataApi( httpClient: httpClient, modelName: 'user_content_preferences', fromJson: UserContentPreferences.fromJson, toJson: (prefs) => prefs.toJson(), - logger: Logger('HtDataApi'), + logger: Logger('DataApi'), ); - userAppSettingsClient = HtDataApi( + userAppSettingsClient = DataApi( httpClient: httpClient, modelName: 'user_app_settings', fromJson: UserAppSettings.fromJson, toJson: (settings) => settings.toJson(), - logger: Logger('HtDataApi'), + logger: Logger('DataApi'), ); - remoteConfigClient = HtDataApi( + remoteConfigClient = DataApi( httpClient: httpClient, modelName: 'remote_config', fromJson: RemoteConfig.fromJson, toJson: (config) => config.toJson(), - logger: Logger('HtDataApi'), + logger: Logger('DataApi'), ); - dashboardSummaryClient = HtDataApi( + dashboardSummaryClient = DataApi( httpClient: httpClient, modelName: 'dashboard_summary', fromJson: DashboardSummary.fromJson, toJson: (summary) => summary.toJson(), - logger: Logger('HtDataApi'), + logger: Logger('DataApi'), ); } else { - headlinesClient = HtDataApi( + headlinesClient = DataApi( httpClient: httpClient!, modelName: 'headline', fromJson: Headline.fromJson, toJson: (headline) => headline.toJson(), - logger: Logger('HtDataApi'), + logger: Logger('DataApi'), ); - topicsClient = HtDataApi( + topicsClient = DataApi( httpClient: httpClient, modelName: 'topic', fromJson: Topic.fromJson, toJson: (topic) => topic.toJson(), - logger: Logger('HtDataApi'), + logger: Logger('DataApi'), ); - countriesClient = HtDataApi( + countriesClient = DataApi( httpClient: httpClient, modelName: 'country', fromJson: Country.fromJson, toJson: (country) => country.toJson(), - logger: Logger('HtDataApi'), + logger: Logger('DataApi'), ); - sourcesClient = HtDataApi( + sourcesClient = DataApi( httpClient: httpClient, modelName: 'source', fromJson: Source.fromJson, toJson: (source) => source.toJson(), - logger: Logger('HtDataApi'), + logger: Logger('DataApi'), ); - userContentPreferencesClient = HtDataApi( + userContentPreferencesClient = DataApi( httpClient: httpClient, modelName: 'user_content_preferences', fromJson: UserContentPreferences.fromJson, toJson: (prefs) => prefs.toJson(), - logger: Logger('HtDataApi'), + logger: Logger('DataApi'), ); - userAppSettingsClient = HtDataApi( + userAppSettingsClient = DataApi( httpClient: httpClient, modelName: 'user_app_settings', fromJson: UserAppSettings.fromJson, toJson: (settings) => settings.toJson(), - logger: Logger('HtDataApi'), + logger: Logger('DataApi'), ); - remoteConfigClient = HtDataApi( + remoteConfigClient = DataApi( httpClient: httpClient, modelName: 'remote_config', fromJson: RemoteConfig.fromJson, toJson: (config) => config.toJson(), - logger: Logger('HtDataApi'), + logger: Logger('DataApi'), ); - dashboardSummaryClient = HtDataApi( + dashboardSummaryClient = DataApi( httpClient: httpClient, modelName: 'dashboard_summary', fromJson: DashboardSummary.fromJson, toJson: (summary) => summary.toJson(), - logger: Logger('HtDataApi'), + logger: Logger('DataApi'), ); } - final headlinesRepository = HtDataRepository( + final headlinesRepository = DataRepository( dataClient: headlinesClient, ); - final topicsRepository = HtDataRepository( - dataClient: topicsClient, - ); - final countriesRepository = HtDataRepository( + final topicsRepository = DataRepository(dataClient: topicsClient); + final countriesRepository = DataRepository( dataClient: countriesClient, ); - final sourcesRepository = HtDataRepository(dataClient: sourcesClient); + final sourcesRepository = DataRepository(dataClient: sourcesClient); final userContentPreferencesRepository = - HtDataRepository( + DataRepository( dataClient: userContentPreferencesClient, ); - final userAppSettingsRepository = HtDataRepository( + final userAppSettingsRepository = DataRepository( dataClient: userAppSettingsClient, ); - final remoteConfigRepository = HtDataRepository( + final remoteConfigRepository = DataRepository( dataClient: remoteConfigClient, ); - final dashboardSummaryRepository = HtDataRepository( + final dashboardSummaryRepository = DataRepository( dataClient: dashboardSummaryClient, ); return App( - htAuthenticationRepository: authenticationRepository, - htHeadlinesRepository: headlinesRepository, - htTopicsRepository: topicsRepository, - htCountriesRepository: countriesRepository, - htSourcesRepository: sourcesRepository, - htUserAppSettingsRepository: userAppSettingsRepository, - htUserContentPreferencesRepository: userContentPreferencesRepository, - htRemoteConfigRepository: remoteConfigRepository, - htDashboardSummaryRepository: dashboardSummaryRepository, - kvStorageService: kvStorage, + authenticationRepository: authenticationRepository, + headlinesRepository: headlinesRepository, + topicsRepository: topicsRepository, + countriesRepository: countriesRepository, + sourcesRepository: sourcesRepository, + userAppSettingsRepository: userAppSettingsRepository, + userContentPreferencesRepository: userContentPreferencesRepository, + remoteConfigRepository: remoteConfigRepository, + dashboardSummaryRepository: dashboardSummaryRepository, + storageService: kvStorage, environment: environment, ); } diff --git a/lib/content_management/bloc/content_management_bloc.dart b/lib/content_management/bloc/content_management_bloc.dart index 12d5b43..1de06ba 100644 --- a/lib/content_management/bloc/content_management_bloc.dart +++ b/lib/content_management/bloc/content_management_bloc.dart @@ -1,7 +1,7 @@ import 'package:bloc/bloc.dart'; +import 'package:core/core.dart'; +import 'package:data_repository/data_repository.dart'; import 'package:equatable/equatable.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; part 'content_management_event.dart'; part 'content_management_state.dart'; @@ -21,9 +21,9 @@ enum ContentManagementTab { class ContentManagementBloc extends Bloc { ContentManagementBloc({ - required HtDataRepository headlinesRepository, - required HtDataRepository topicsRepository, - required HtDataRepository sourcesRepository, + required DataRepository headlinesRepository, + required DataRepository topicsRepository, + required DataRepository sourcesRepository, }) : _headlinesRepository = headlinesRepository, _topicsRepository = topicsRepository, _sourcesRepository = sourcesRepository, @@ -40,9 +40,9 @@ class ContentManagementBloc on(_onDeleteSourceRequested); } - final HtDataRepository _headlinesRepository; - final HtDataRepository _topicsRepository; - final HtDataRepository _sourcesRepository; + final DataRepository _headlinesRepository; + final DataRepository _topicsRepository; + final DataRepository _sourcesRepository; void _onContentManagementTabChanged( ContentManagementTabChanged event, @@ -74,7 +74,7 @@ class ContentManagementBloc headlinesHasMore: paginatedHeadlines.hasMore, ), ); - } on HtHttpException catch (e) { + } on HttpException catch (e) { emit( state.copyWith( headlinesStatus: ContentManagementStatus.failure, @@ -101,7 +101,7 @@ class ContentManagementBloc .where((h) => h.id != event.id) .toList(); emit(state.copyWith(headlines: updatedHeadlines)); - } on HtHttpException catch (e) { + } on HttpException catch (e) { emit( state.copyWith( headlinesStatus: ContentManagementStatus.failure, @@ -153,7 +153,7 @@ class ContentManagementBloc topicsHasMore: paginatedTopics.hasMore, ), ); - } on HtHttpException catch (e) { + } on HttpException catch (e) { emit( state.copyWith( topicsStatus: ContentManagementStatus.failure, @@ -180,7 +180,7 @@ class ContentManagementBloc .where((c) => c.id != event.id) .toList(); emit(state.copyWith(topics: updatedTopics)); - } on HtHttpException catch (e) { + } on HttpException catch (e) { emit( state.copyWith( topicsStatus: ContentManagementStatus.failure, @@ -232,7 +232,7 @@ class ContentManagementBloc sourcesHasMore: paginatedSources.hasMore, ), ); - } on HtHttpException catch (e) { + } on HttpException catch (e) { emit( state.copyWith( sourcesStatus: ContentManagementStatus.failure, @@ -259,7 +259,7 @@ class ContentManagementBloc .where((s) => s.id != event.id) .toList(); emit(state.copyWith(sources: updatedSources)); - } on HtHttpException catch (e) { + } on HttpException catch (e) { emit( state.copyWith( sourcesStatus: ContentManagementStatus.failure, diff --git a/lib/content_management/bloc/content_management_state.dart b/lib/content_management/bloc/content_management_state.dart index b0cc0dd..d71a388 100644 --- a/lib/content_management/bloc/content_management_state.dart +++ b/lib/content_management/bloc/content_management_state.dart @@ -75,7 +75,7 @@ class ContentManagementState extends Equatable { final bool sourcesHasMore; /// The error describing an operation failure, if any. - final HtHttpException? exception; + final HttpException? exception; /// Creates a copy of this [ContentManagementState] with updated values. ContentManagementState copyWith({ @@ -92,7 +92,7 @@ class ContentManagementState extends Equatable { List? sources, String? sourcesCursor, bool? sourcesHasMore, - HtHttpException? exception, + HttpException? exception, }) { return ContentManagementState( activeTab: activeTab ?? this.activeTab, diff --git a/lib/content_management/bloc/create_headline/create_headline_bloc.dart b/lib/content_management/bloc/create_headline/create_headline_bloc.dart index d3b3488..a179def 100644 --- a/lib/content_management/bloc/create_headline/create_headline_bloc.dart +++ b/lib/content_management/bloc/create_headline/create_headline_bloc.dart @@ -1,8 +1,8 @@ import 'package:bloc/bloc.dart'; +import 'package:core/core.dart'; +import 'package:data_repository/data_repository.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; import 'package:uuid/uuid.dart'; part 'create_headline_event.dart'; @@ -13,10 +13,10 @@ class CreateHeadlineBloc extends Bloc { /// {@macro create_headline_bloc} CreateHeadlineBloc({ - required HtDataRepository headlinesRepository, - required HtDataRepository sourcesRepository, - required HtDataRepository topicsRepository, - required HtDataRepository countriesRepository, + required DataRepository headlinesRepository, + required DataRepository sourcesRepository, + required DataRepository topicsRepository, + required DataRepository countriesRepository, }) : _headlinesRepository = headlinesRepository, _sourcesRepository = sourcesRepository, _topicsRepository = topicsRepository, @@ -34,10 +34,10 @@ class CreateHeadlineBloc on(_onSubmitted); } - final HtDataRepository _headlinesRepository; - final HtDataRepository _sourcesRepository; - final HtDataRepository _topicsRepository; - final HtDataRepository _countriesRepository; + final DataRepository _headlinesRepository; + final DataRepository _sourcesRepository; + final DataRepository _topicsRepository; + final DataRepository _countriesRepository; final _uuid = const Uuid(); Future _onDataLoaded( @@ -68,13 +68,8 @@ class CreateHeadlineBloc countries: countries, ), ); - } on HtHttpException catch (e) { - emit( - state.copyWith( - status: CreateHeadlineStatus.failure, - exception: e, - ), - ); + } on HttpException catch (e) { + emit(state.copyWith(status: CreateHeadlineStatus.failure, exception: e)); } catch (e) { emit( state.copyWith( @@ -176,13 +171,8 @@ class CreateHeadlineBloc createdHeadline: newHeadline, ), ); - } on HtHttpException catch (e) { - emit( - state.copyWith( - status: CreateHeadlineStatus.failure, - exception: e, - ), - ); + } on HttpException catch (e) { + emit(state.copyWith(status: CreateHeadlineStatus.failure, exception: e)); } catch (e) { emit( state.copyWith( diff --git a/lib/content_management/bloc/create_headline/create_headline_state.dart b/lib/content_management/bloc/create_headline/create_headline_state.dart index 7293482..0739db1 100644 --- a/lib/content_management/bloc/create_headline/create_headline_state.dart +++ b/lib/content_management/bloc/create_headline/create_headline_state.dart @@ -49,7 +49,7 @@ final class CreateHeadlineState extends Equatable { final List topics; final List countries; final ContentStatus contentStatus; - final HtHttpException? exception; + final HttpException? exception; final Headline? createdHeadline; /// Returns true if the form is valid and can be submitted. @@ -75,7 +75,7 @@ final class CreateHeadlineState extends Equatable { List? topics, List? countries, ContentStatus? contentStatus, - HtHttpException? exception, + HttpException? exception, Headline? createdHeadline, }) { return CreateHeadlineState( diff --git a/lib/content_management/bloc/create_source/create_source_bloc.dart b/lib/content_management/bloc/create_source/create_source_bloc.dart index 9cf6b1c..286f675 100644 --- a/lib/content_management/bloc/create_source/create_source_bloc.dart +++ b/lib/content_management/bloc/create_source/create_source_bloc.dart @@ -1,8 +1,8 @@ import 'package:bloc/bloc.dart'; +import 'package:core/core.dart'; +import 'package:data_repository/data_repository.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; import 'package:uuid/uuid.dart'; part 'create_source_event.dart'; @@ -12,8 +12,8 @@ part 'create_source_state.dart'; class CreateSourceBloc extends Bloc { /// {@macro create_source_bloc} CreateSourceBloc({ - required HtDataRepository sourcesRepository, - required HtDataRepository countriesRepository, + required DataRepository sourcesRepository, + required DataRepository countriesRepository, }) : _sourcesRepository = sourcesRepository, _countriesRepository = countriesRepository, super(const CreateSourceState()) { @@ -28,8 +28,8 @@ class CreateSourceBloc extends Bloc { on(_onSubmitted); } - final HtDataRepository _sourcesRepository; - final HtDataRepository _countriesRepository; + final DataRepository _sourcesRepository; + final DataRepository _countriesRepository; final _uuid = const Uuid(); Future _onDataLoaded( @@ -47,13 +47,8 @@ class CreateSourceBloc extends Bloc { countries: countries, ), ); - } on HtHttpException catch (e) { - emit( - state.copyWith( - status: CreateSourceStatus.failure, - exception: e, - ), - ); + } on HttpException catch (e) { + emit(state.copyWith(status: CreateSourceStatus.failure, exception: e)); } catch (e) { emit( state.copyWith( @@ -147,13 +142,8 @@ class CreateSourceBloc extends Bloc { createdSource: newSource, ), ); - } on HtHttpException catch (e) { - emit( - state.copyWith( - status: CreateSourceStatus.failure, - exception: e, - ), - ); + } on HttpException catch (e) { + emit(state.copyWith(status: CreateSourceStatus.failure, exception: e)); } catch (e) { emit( state.copyWith( diff --git a/lib/content_management/bloc/create_source/create_source_state.dart b/lib/content_management/bloc/create_source/create_source_state.dart index 0384e38..32f3657 100644 --- a/lib/content_management/bloc/create_source/create_source_state.dart +++ b/lib/content_management/bloc/create_source/create_source_state.dart @@ -44,7 +44,7 @@ final class CreateSourceState extends Equatable { final Country? headquarters; final List countries; final ContentStatus contentStatus; - final HtHttpException? exception; + final HttpException? exception; final Source? createdSource; /// Returns true if the form is valid and can be submitted. @@ -66,7 +66,7 @@ final class CreateSourceState extends Equatable { ValueGetter? headquarters, List? countries, ContentStatus? contentStatus, - HtHttpException? exception, + HttpException? exception, Source? createdSource, }) { return CreateSourceState( diff --git a/lib/content_management/bloc/create_topic/create_topic_bloc.dart b/lib/content_management/bloc/create_topic/create_topic_bloc.dart index 92bc7b0..23767e1 100644 --- a/lib/content_management/bloc/create_topic/create_topic_bloc.dart +++ b/lib/content_management/bloc/create_topic/create_topic_bloc.dart @@ -1,7 +1,7 @@ import 'package:bloc/bloc.dart'; +import 'package:core/core.dart'; +import 'package:data_repository/data_repository.dart'; import 'package:equatable/equatable.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; import 'package:uuid/uuid.dart'; part 'create_topic_event.dart'; @@ -10,10 +10,9 @@ part 'create_topic_state.dart'; /// A BLoC to manage the state of creating a new topic. class CreateTopicBloc extends Bloc { /// {@macro create_topic_bloc} - CreateTopicBloc({ - required HtDataRepository topicsRepository, - }) : _topicsRepository = topicsRepository, - super(const CreateTopicState()) { + CreateTopicBloc({required DataRepository topicsRepository}) + : _topicsRepository = topicsRepository, + super(const CreateTopicState()) { on(_onNameChanged); on(_onDescriptionChanged); on(_onIconUrlChanged); @@ -21,19 +20,14 @@ class CreateTopicBloc extends Bloc { on(_onSubmitted); } - final HtDataRepository _topicsRepository; + final DataRepository _topicsRepository; final _uuid = const Uuid(); void _onNameChanged( CreateTopicNameChanged event, Emitter emit, ) { - emit( - state.copyWith( - name: event.name, - status: CreateTopicStatus.initial, - ), - ); + emit(state.copyWith(name: event.name, status: CreateTopicStatus.initial)); } void _onDescriptionChanged( @@ -53,10 +47,7 @@ class CreateTopicBloc extends Bloc { Emitter emit, ) { emit( - state.copyWith( - iconUrl: event.iconUrl, - status: CreateTopicStatus.initial, - ), + state.copyWith(iconUrl: event.iconUrl, status: CreateTopicStatus.initial), ); } @@ -98,13 +89,8 @@ class CreateTopicBloc extends Bloc { createdTopic: newTopic, ), ); - } on HtHttpException catch (e) { - emit( - state.copyWith( - status: CreateTopicStatus.failure, - exception: e, - ), - ); + } on HttpException catch (e) { + emit(state.copyWith(status: CreateTopicStatus.failure, exception: e)); } catch (e) { emit( state.copyWith( diff --git a/lib/content_management/bloc/create_topic/create_topic_state.dart b/lib/content_management/bloc/create_topic/create_topic_state.dart index a25b92f..8476105 100644 --- a/lib/content_management/bloc/create_topic/create_topic_state.dart +++ b/lib/content_management/bloc/create_topic/create_topic_state.dart @@ -33,7 +33,7 @@ final class CreateTopicState extends Equatable { final String description; final String iconUrl; final ContentStatus contentStatus; - final HtHttpException? exception; + final HttpException? exception; final Topic? createdTopic; /// Returns true if the form is valid and can be submitted. @@ -47,7 +47,7 @@ final class CreateTopicState extends Equatable { String? description, String? iconUrl, ContentStatus? contentStatus, - HtHttpException? exception, + HttpException? exception, Topic? createdTopic, }) { return CreateTopicState( diff --git a/lib/content_management/bloc/edit_headline/edit_headline_bloc.dart b/lib/content_management/bloc/edit_headline/edit_headline_bloc.dart index 6e8fe24..07540d4 100644 --- a/lib/content_management/bloc/edit_headline/edit_headline_bloc.dart +++ b/lib/content_management/bloc/edit_headline/edit_headline_bloc.dart @@ -1,8 +1,8 @@ import 'package:bloc/bloc.dart'; +import 'package:core/core.dart'; +import 'package:data_repository/data_repository.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; part 'edit_headline_event.dart'; part 'edit_headline_state.dart'; @@ -11,10 +11,10 @@ part 'edit_headline_state.dart'; class EditHeadlineBloc extends Bloc { /// {@macro edit_headline_bloc} EditHeadlineBloc({ - required HtDataRepository headlinesRepository, - required HtDataRepository sourcesRepository, - required HtDataRepository topicsRepository, - required HtDataRepository countriesRepository, + required DataRepository headlinesRepository, + required DataRepository sourcesRepository, + required DataRepository topicsRepository, + required DataRepository countriesRepository, required String headlineId, }) : _headlinesRepository = headlinesRepository, _sourcesRepository = sourcesRepository, @@ -34,10 +34,10 @@ class EditHeadlineBloc extends Bloc { on(_onSubmitted); } - final HtDataRepository _headlinesRepository; - final HtDataRepository _sourcesRepository; - final HtDataRepository _topicsRepository; - final HtDataRepository _countriesRepository; + final DataRepository _headlinesRepository; + final DataRepository _sourcesRepository; + final DataRepository _topicsRepository; + final DataRepository _countriesRepository; final String _headlineId; Future _onLoaded( @@ -80,13 +80,8 @@ class EditHeadlineBloc extends Bloc { contentStatus: headline.status, ), ); - } on HtHttpException catch (e) { - emit( - state.copyWith( - status: EditHeadlineStatus.failure, - exception: e, - ), - ); + } on HttpException catch (e) { + emit(state.copyWith(status: EditHeadlineStatus.failure, exception: e)); } catch (e) { emit( state.copyWith( @@ -225,13 +220,8 @@ class EditHeadlineBloc extends Bloc { updatedHeadline: updatedHeadline, ), ); - } on HtHttpException catch (e) { - emit( - state.copyWith( - status: EditHeadlineStatus.failure, - exception: e, - ), - ); + } on HttpException catch (e) { + emit(state.copyWith(status: EditHeadlineStatus.failure, exception: e)); } catch (e) { emit( state.copyWith( diff --git a/lib/content_management/bloc/edit_headline/edit_headline_state.dart b/lib/content_management/bloc/edit_headline/edit_headline_state.dart index ffbccc3..fba983f 100644 --- a/lib/content_management/bloc/edit_headline/edit_headline_state.dart +++ b/lib/content_management/bloc/edit_headline/edit_headline_state.dart @@ -51,7 +51,7 @@ final class EditHeadlineState extends Equatable { final List topics; final List countries; final ContentStatus contentStatus; - final HtHttpException? exception; + final HttpException? exception; final Headline? updatedHeadline; /// Returns true if the form is valid and can be submitted. @@ -78,7 +78,7 @@ final class EditHeadlineState extends Equatable { List? topics, List? countries, ContentStatus? contentStatus, - HtHttpException? exception, + HttpException? exception, Headline? updatedHeadline, }) { return EditHeadlineState( diff --git a/lib/content_management/bloc/edit_source/edit_source_bloc.dart b/lib/content_management/bloc/edit_source/edit_source_bloc.dart index 1181a03..3ed56e9 100644 --- a/lib/content_management/bloc/edit_source/edit_source_bloc.dart +++ b/lib/content_management/bloc/edit_source/edit_source_bloc.dart @@ -1,9 +1,9 @@ import 'package:bloc/bloc.dart'; +import 'package:core/core.dart'; +import 'package:data_repository/data_repository.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart'; -import 'package:ht_dashboard/l10n/app_localizations.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/app_localizations.dart'; part 'edit_source_event.dart'; part 'edit_source_state.dart'; @@ -12,8 +12,8 @@ part 'edit_source_state.dart'; class EditSourceBloc extends Bloc { /// {@macro edit_source_bloc} EditSourceBloc({ - required HtDataRepository sourcesRepository, - required HtDataRepository countriesRepository, + required DataRepository sourcesRepository, + required DataRepository countriesRepository, required String sourceId, }) : _sourcesRepository = sourcesRepository, _countriesRepository = countriesRepository, @@ -30,8 +30,8 @@ class EditSourceBloc extends Bloc { on(_onSubmitted); } - final HtDataRepository _sourcesRepository; - final HtDataRepository _countriesRepository; + final DataRepository _sourcesRepository; + final DataRepository _countriesRepository; final String _sourceId; Future _onLoaded( @@ -60,13 +60,8 @@ class EditSourceBloc extends Bloc { countries: countries, ), ); - } on HtHttpException catch (e) { - emit( - state.copyWith( - status: EditSourceStatus.failure, - exception: e, - ), - ); + } on HttpException catch (e) { + emit(state.copyWith(status: EditSourceStatus.failure, exception: e)); } catch (e) { emit( state.copyWith( @@ -190,13 +185,8 @@ class EditSourceBloc extends Bloc { updatedSource: updatedSource, ), ); - } on HtHttpException catch (e) { - emit( - state.copyWith( - status: EditSourceStatus.failure, - exception: e, - ), - ); + } on HttpException catch (e) { + emit(state.copyWith(status: EditSourceStatus.failure, exception: e)); } catch (e) { emit( state.copyWith( diff --git a/lib/content_management/bloc/edit_source/edit_source_state.dart b/lib/content_management/bloc/edit_source/edit_source_state.dart index 1943a68..8610f46 100644 --- a/lib/content_management/bloc/edit_source/edit_source_state.dart +++ b/lib/content_management/bloc/edit_source/edit_source_state.dart @@ -45,7 +45,7 @@ final class EditSourceState extends Equatable { final Country? headquarters; final List countries; final ContentStatus contentStatus; - final HtHttpException? exception; + final HttpException? exception; final Source? updatedSource; /// Returns true if the form is valid and can be submitted. @@ -68,7 +68,7 @@ final class EditSourceState extends Equatable { ValueGetter? headquarters, List? countries, ContentStatus? contentStatus, - HtHttpException? exception, + HttpException? exception, Source? updatedSource, }) { return EditSourceState( diff --git a/lib/content_management/bloc/edit_topic/edit_topic_bloc.dart b/lib/content_management/bloc/edit_topic/edit_topic_bloc.dart index a15308f..552b575 100644 --- a/lib/content_management/bloc/edit_topic/edit_topic_bloc.dart +++ b/lib/content_management/bloc/edit_topic/edit_topic_bloc.dart @@ -1,7 +1,7 @@ import 'package:bloc/bloc.dart'; +import 'package:core/core.dart'; +import 'package:data_repository/data_repository.dart'; import 'package:equatable/equatable.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; part 'edit_topic_event.dart'; part 'edit_topic_state.dart'; @@ -10,7 +10,7 @@ part 'edit_topic_state.dart'; class EditTopicBloc extends Bloc { /// {@macro edit_topic_bloc} EditTopicBloc({ - required HtDataRepository topicsRepository, + required DataRepository topicsRepository, required String topicId, }) : _topicsRepository = topicsRepository, _topicId = topicId, @@ -23,7 +23,7 @@ class EditTopicBloc extends Bloc { on(_onSubmitted); } - final HtDataRepository _topicsRepository; + final DataRepository _topicsRepository; final String _topicId; Future _onLoaded( @@ -43,13 +43,8 @@ class EditTopicBloc extends Bloc { contentStatus: topic.status, ), ); - } on HtHttpException catch (e) { - emit( - state.copyWith( - status: EditTopicStatus.failure, - exception: e, - ), - ); + } on HttpException catch (e) { + emit(state.copyWith(status: EditTopicStatus.failure, exception: e)); } catch (e) { emit( state.copyWith( @@ -90,10 +85,7 @@ class EditTopicBloc extends Bloc { Emitter emit, ) { emit( - state.copyWith( - iconUrl: event.iconUrl, - status: EditTopicStatus.initial, - ), + state.copyWith(iconUrl: event.iconUrl, status: EditTopicStatus.initial), ); } @@ -140,23 +132,15 @@ class EditTopicBloc extends Bloc { updatedAt: DateTime.now(), ); - await _topicsRepository.update( - id: _topicId, - item: updatedTopic, - ); + await _topicsRepository.update(id: _topicId, item: updatedTopic); emit( state.copyWith( status: EditTopicStatus.success, updatedTopic: updatedTopic, ), ); - } on HtHttpException catch (e) { - emit( - state.copyWith( - status: EditTopicStatus.failure, - exception: e, - ), - ); + } on HttpException catch (e) { + emit(state.copyWith(status: EditTopicStatus.failure, exception: e)); } catch (e) { emit( state.copyWith( diff --git a/lib/content_management/bloc/edit_topic/edit_topic_state.dart b/lib/content_management/bloc/edit_topic/edit_topic_state.dart index 86d565b..fd64985 100644 --- a/lib/content_management/bloc/edit_topic/edit_topic_state.dart +++ b/lib/content_management/bloc/edit_topic/edit_topic_state.dart @@ -37,7 +37,7 @@ final class EditTopicState extends Equatable { final String description; final String iconUrl; final ContentStatus contentStatus; - final HtHttpException? exception; + final HttpException? exception; final Topic? updatedTopic; /// Returns true if the form is valid and can be submitted. @@ -52,7 +52,7 @@ final class EditTopicState extends Equatable { String? description, String? iconUrl, ContentStatus? contentStatus, - HtHttpException? exception, + HttpException? exception, Topic? updatedTopic, }) { return EditTopicState( diff --git a/lib/content_management/view/content_management_page.dart b/lib/content_management/view/content_management_page.dart index 2e02365..a5cb580 100644 --- a/lib/content_management/view/content_management_page.dart +++ b/lib/content_management/view/content_management_page.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/bloc/content_management_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/view/headlines_page.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/view/sources_page.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/view/topics_page.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/router/routes.dart'; import 'package:go_router/go_router.dart'; -import 'package:ht_dashboard/content_management/bloc/content_management_bloc.dart'; -import 'package:ht_dashboard/content_management/view/headlines_page.dart'; -import 'package:ht_dashboard/content_management/view/sources_page.dart'; -import 'package:ht_dashboard/content_management/view/topics_page.dart'; -import 'package:ht_dashboard/l10n/l10n.dart'; -import 'package:ht_dashboard/router/routes.dart'; -import 'package:ht_ui_kit/ht_ui_kit.dart'; +import 'package:ui_kit/ui_kit.dart'; /// {@template content_management_page} /// A page for Content Management with tabbed navigation for sub-sections. @@ -115,11 +115,7 @@ class _ContentManagementPageState extends State ), body: TabBarView( controller: _tabController, - children: const [ - HeadlinesPage(), - TopicPage(), - SourcesPage(), - ], + children: const [HeadlinesPage(), TopicPage(), SourcesPage()], ), ), ); diff --git a/lib/content_management/view/create_headline_page.dart b/lib/content_management/view/create_headline_page.dart index bf44367..ec040bc 100644 --- a/lib/content_management/view/create_headline_page.dart +++ b/lib/content_management/view/create_headline_page.dart @@ -1,13 +1,13 @@ +import 'package:core/core.dart'; +import 'package:data_repository/data_repository.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/bloc/content_management_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/bloc/create_headline/create_headline_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/shared/shared.dart'; import 'package:go_router/go_router.dart'; -import 'package:ht_dashboard/content_management/bloc/content_management_bloc.dart'; -import 'package:ht_dashboard/content_management/bloc/create_headline/create_headline_bloc.dart'; -import 'package:ht_dashboard/l10n/l10n.dart'; -import 'package:ht_dashboard/shared/shared.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; -import 'package:ht_ui_kit/ht_ui_kit.dart'; +import 'package:ui_kit/ui_kit.dart'; /// {@template create_headline_page} /// A page for creating a new headline. @@ -21,10 +21,10 @@ class CreateHeadlinePage extends StatelessWidget { Widget build(BuildContext context) { return BlocProvider( create: (context) => CreateHeadlineBloc( - headlinesRepository: context.read>(), - sourcesRepository: context.read>(), - topicsRepository: context.read>(), - countriesRepository: context.read>(), + headlinesRepository: context.read>(), + sourcesRepository: context.read>(), + topicsRepository: context.read>(), + countriesRepository: context.read>(), )..add(const CreateHeadlineDataLoaded()), child: const _CreateHeadlineView(), ); diff --git a/lib/content_management/view/create_source_page.dart b/lib/content_management/view/create_source_page.dart index d09fef4..a9961bf 100644 --- a/lib/content_management/view/create_source_page.dart +++ b/lib/content_management/view/create_source_page.dart @@ -1,14 +1,14 @@ +import 'package:core/core.dart'; +import 'package:data_repository/data_repository.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/bloc/content_management_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/bloc/create_source/create_source_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/bloc/edit_source/edit_source_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/shared/shared.dart'; import 'package:go_router/go_router.dart'; -import 'package:ht_dashboard/content_management/bloc/content_management_bloc.dart'; -import 'package:ht_dashboard/content_management/bloc/create_source/create_source_bloc.dart'; -import 'package:ht_dashboard/content_management/bloc/edit_source/edit_source_bloc.dart'; -import 'package:ht_dashboard/l10n/l10n.dart'; -import 'package:ht_dashboard/shared/shared.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; -import 'package:ht_ui_kit/ht_ui_kit.dart'; +import 'package:ui_kit/ui_kit.dart'; /// {@template create_source_page} /// A page for creating a new source. @@ -22,8 +22,8 @@ class CreateSourcePage extends StatelessWidget { Widget build(BuildContext context) { return BlocProvider( create: (context) => CreateSourceBloc( - sourcesRepository: context.read>(), - countriesRepository: context.read>(), + sourcesRepository: context.read>(), + countriesRepository: context.read>(), )..add(const CreateSourceDataLoaded()), child: const _CreateSourceView(), ); diff --git a/lib/content_management/view/create_topic_page.dart b/lib/content_management/view/create_topic_page.dart index 55bbaa2..575ca93 100644 --- a/lib/content_management/view/create_topic_page.dart +++ b/lib/content_management/view/create_topic_page.dart @@ -1,13 +1,13 @@ +import 'package:core/core.dart'; +import 'package:data_repository/data_repository.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/bloc/content_management_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/bloc/create_topic/create_topic_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/shared/shared.dart'; import 'package:go_router/go_router.dart'; -import 'package:ht_dashboard/content_management/bloc/content_management_bloc.dart'; -import 'package:ht_dashboard/content_management/bloc/create_topic/create_topic_bloc.dart'; -import 'package:ht_dashboard/l10n/l10n.dart'; -import 'package:ht_dashboard/shared/shared.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; -import 'package:ht_ui_kit/ht_ui_kit.dart'; +import 'package:ui_kit/ui_kit.dart'; /// {@template create_topic_page} /// A page for creating a new topic. @@ -21,7 +21,7 @@ class CreateTopicPage extends StatelessWidget { Widget build(BuildContext context) { return BlocProvider( create: (context) => CreateTopicBloc( - topicsRepository: context.read>(), + topicsRepository: context.read>(), ), child: const _CreateTopicView(), ); diff --git a/lib/content_management/view/edit_headline_page.dart b/lib/content_management/view/edit_headline_page.dart index f27badb..3f5f4aa 100644 --- a/lib/content_management/view/edit_headline_page.dart +++ b/lib/content_management/view/edit_headline_page.dart @@ -1,13 +1,13 @@ +import 'package:core/core.dart'; +import 'package:data_repository/data_repository.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/bloc/content_management_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/bloc/edit_headline/edit_headline_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/shared/shared.dart'; import 'package:go_router/go_router.dart'; -import 'package:ht_dashboard/content_management/bloc/content_management_bloc.dart'; -import 'package:ht_dashboard/content_management/bloc/edit_headline/edit_headline_bloc.dart'; -import 'package:ht_dashboard/l10n/l10n.dart'; -import 'package:ht_dashboard/shared/shared.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; -import 'package:ht_ui_kit/ht_ui_kit.dart'; +import 'package:ui_kit/ui_kit.dart'; /// {@template edit_headline_page} /// A page for editing an existing headline. @@ -24,10 +24,10 @@ class EditHeadlinePage extends StatelessWidget { Widget build(BuildContext context) { return BlocProvider( create: (context) => EditHeadlineBloc( - headlinesRepository: context.read>(), - sourcesRepository: context.read>(), - topicsRepository: context.read>(), - countriesRepository: context.read>(), + headlinesRepository: context.read>(), + sourcesRepository: context.read>(), + topicsRepository: context.read>(), + countriesRepository: context.read>(), headlineId: headlineId, )..add(const EditHeadlineLoaded()), child: const _EditHeadlineView(), @@ -111,9 +111,7 @@ class _EditHeadlineViewState extends State<_EditHeadlineView> { ScaffoldMessenger.of(context) ..hideCurrentSnackBar() ..showSnackBar( - SnackBar( - content: Text(l10n.headlineUpdatedSuccessfully), - ), + SnackBar(content: Text(l10n.headlineUpdatedSuccessfully)), ); context.read().add( HeadlineUpdated(state.updatedHeadline!), diff --git a/lib/content_management/view/edit_source_page.dart b/lib/content_management/view/edit_source_page.dart index 90c6d4d..49abcab 100644 --- a/lib/content_management/view/edit_source_page.dart +++ b/lib/content_management/view/edit_source_page.dart @@ -1,13 +1,13 @@ +import 'package:core/core.dart'; +import 'package:data_repository/data_repository.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/bloc/content_management_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/bloc/edit_source/edit_source_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/shared/shared.dart'; import 'package:go_router/go_router.dart'; -import 'package:ht_dashboard/content_management/bloc/content_management_bloc.dart'; -import 'package:ht_dashboard/content_management/bloc/edit_source/edit_source_bloc.dart'; -import 'package:ht_dashboard/l10n/l10n.dart'; -import 'package:ht_dashboard/shared/shared.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; -import 'package:ht_ui_kit/ht_ui_kit.dart'; +import 'package:ui_kit/ui_kit.dart'; /// {@template edit_source_page} /// A page for editing an existing source. @@ -24,8 +24,8 @@ class EditSourcePage extends StatelessWidget { Widget build(BuildContext context) { return BlocProvider( create: (context) => EditSourceBloc( - sourcesRepository: context.read>(), - countriesRepository: context.read>(), + sourcesRepository: context.read>(), + countriesRepository: context.read>(), sourceId: sourceId, )..add(const EditSourceLoaded()), child: const _EditSourceView(), diff --git a/lib/content_management/view/edit_topic_page.dart b/lib/content_management/view/edit_topic_page.dart index 625daee..9754afe 100644 --- a/lib/content_management/view/edit_topic_page.dart +++ b/lib/content_management/view/edit_topic_page.dart @@ -1,13 +1,13 @@ +import 'package:core/core.dart'; +import 'package:data_repository/data_repository.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/bloc/content_management_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/bloc/edit_topic/edit_topic_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/shared/shared.dart'; import 'package:go_router/go_router.dart'; -import 'package:ht_dashboard/content_management/bloc/content_management_bloc.dart'; -import 'package:ht_dashboard/content_management/bloc/edit_topic/edit_topic_bloc.dart'; -import 'package:ht_dashboard/l10n/l10n.dart'; -import 'package:ht_dashboard/shared/shared.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; -import 'package:ht_ui_kit/ht_ui_kit.dart'; +import 'package:ui_kit/ui_kit.dart'; /// {@template edit_topic_page} /// A page for editing an existing topic. @@ -24,7 +24,7 @@ class EditTopicPage extends StatelessWidget { Widget build(BuildContext context) { return BlocProvider( create: (context) => EditTopicBloc( - topicsRepository: context.read>(), + topicsRepository: context.read>(), topicId: topicId, )..add(const EditTopicLoaded()), child: const _EditTopicView(), @@ -141,9 +141,8 @@ class _EditTopicViewState extends State<_EditTopicView> { state.initialTopic == null) { return FailureStateWidget( exception: state.exception!, - onRetry: () => context.read().add( - const EditTopicLoaded(), - ), + onRetry: () => + context.read().add(const EditTopicLoaded()), ); } diff --git a/lib/content_management/view/headlines_page.dart b/lib/content_management/view/headlines_page.dart index 634a6cd..8555d38 100644 --- a/lib/content_management/view/headlines_page.dart +++ b/lib/content_management/view/headlines_page.dart @@ -1,15 +1,15 @@ +import 'package:core/core.dart'; import 'package:data_table_2/data_table_2.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/bloc/content_management_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/app_localizations.dart'; // Corrected import +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/router/routes.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/shared/extensions/content_status_l10n.dart'; import 'package:go_router/go_router.dart'; -import 'package:ht_dashboard/content_management/bloc/content_management_bloc.dart'; -import 'package:ht_dashboard/l10n/app_localizations.dart'; // Corrected import -import 'package:ht_dashboard/l10n/l10n.dart'; -import 'package:ht_dashboard/router/routes.dart'; -import 'package:ht_dashboard/shared/extensions/content_status_l10n.dart'; -import 'package:ht_shared/ht_shared.dart'; -import 'package:ht_ui_kit/ht_ui_kit.dart'; import 'package:intl/intl.dart'; +import 'package:ui_kit/ui_kit.dart'; /// {@template headlines_page} /// A page for displaying and managing Headlines in a tabular format. @@ -57,29 +57,15 @@ class _HeadlinesPageState extends State { } if (state.headlines.isEmpty) { - return Center( - child: Text(l10n.noHeadlinesFound), - ); + return Center(child: Text(l10n.noHeadlinesFound)); } return PaginatedDataTable2( columns: [ - DataColumn2( - label: Text(l10n.headlineTitle), - size: ColumnSize.L, - ), - DataColumn2( - label: Text(l10n.sourceName), - size: ColumnSize.M, - ), - DataColumn2( - label: Text(l10n.status), - size: ColumnSize.S, - ), - DataColumn2( - label: Text(l10n.lastUpdated), - size: ColumnSize.M, - ), + DataColumn2(label: Text(l10n.headlineTitle), size: ColumnSize.L), + DataColumn2(label: Text(l10n.sourceName), size: ColumnSize.M), + DataColumn2(label: Text(l10n.status), size: ColumnSize.S), + DataColumn2(label: Text(l10n.lastUpdated), size: ColumnSize.M), DataColumn2( label: Text(l10n.actions), size: ColumnSize.S, diff --git a/lib/content_management/view/sources_page.dart b/lib/content_management/view/sources_page.dart index 9474a3e..1fb9de4 100644 --- a/lib/content_management/view/sources_page.dart +++ b/lib/content_management/view/sources_page.dart @@ -1,16 +1,16 @@ +import 'package:core/core.dart'; import 'package:data_table_2/data_table_2.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/bloc/content_management_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/bloc/edit_source/edit_source_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/app_localizations.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/router/routes.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/shared/extensions/content_status_l10n.dart'; import 'package:go_router/go_router.dart'; -import 'package:ht_dashboard/content_management/bloc/content_management_bloc.dart'; -import 'package:ht_dashboard/content_management/bloc/edit_source/edit_source_bloc.dart'; -import 'package:ht_dashboard/l10n/app_localizations.dart'; -import 'package:ht_dashboard/l10n/l10n.dart'; -import 'package:ht_dashboard/router/routes.dart'; -import 'package:ht_dashboard/shared/extensions/content_status_l10n.dart'; -import 'package:ht_shared/ht_shared.dart'; -import 'package:ht_ui_kit/ht_ui_kit.dart'; import 'package:intl/intl.dart'; +import 'package:ui_kit/ui_kit.dart'; /// {@template sources_page} /// A page for displaying and managing Sources in a tabular format. @@ -58,29 +58,15 @@ class _SourcesPageState extends State { } if (state.sources.isEmpty) { - return Center( - child: Text(l10n.noSourcesFound), - ); + return Center(child: Text(l10n.noSourcesFound)); } return PaginatedDataTable2( columns: [ - DataColumn2( - label: Text(l10n.sourceName), - size: ColumnSize.L, - ), - DataColumn2( - label: Text(l10n.sourceType), - size: ColumnSize.M, - ), - DataColumn2( - label: Text(l10n.status), - size: ColumnSize.S, - ), - DataColumn2( - label: Text(l10n.lastUpdated), - size: ColumnSize.M, - ), + DataColumn2(label: Text(l10n.sourceName), size: ColumnSize.L), + DataColumn2(label: Text(l10n.sourceType), size: ColumnSize.M), + DataColumn2(label: Text(l10n.status), size: ColumnSize.S), + DataColumn2(label: Text(l10n.lastUpdated), size: ColumnSize.M), DataColumn2( label: Text(l10n.actions), size: ColumnSize.S, diff --git a/lib/content_management/view/topics_page.dart b/lib/content_management/view/topics_page.dart index dc6f189..af06e00 100644 --- a/lib/content_management/view/topics_page.dart +++ b/lib/content_management/view/topics_page.dart @@ -1,15 +1,15 @@ +import 'package:core/core.dart'; import 'package:data_table_2/data_table_2.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/bloc/content_management_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/app_localizations.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/router/routes.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/shared/shared.dart'; import 'package:go_router/go_router.dart'; -import 'package:ht_dashboard/content_management/bloc/content_management_bloc.dart'; -import 'package:ht_dashboard/l10n/app_localizations.dart'; -import 'package:ht_dashboard/l10n/l10n.dart'; -import 'package:ht_dashboard/router/routes.dart'; -import 'package:ht_dashboard/shared/shared.dart'; -import 'package:ht_shared/ht_shared.dart'; -import 'package:ht_ui_kit/ht_ui_kit.dart'; import 'package:intl/intl.dart'; +import 'package:ui_kit/ui_kit.dart'; /// {@template topics_page} /// A page for displaying and managing Topics in a tabular format. @@ -57,25 +57,14 @@ class _TopicPageState extends State { } if (state.topics.isEmpty) { - return Center( - child: Text(l10n.noTopicsFound), - ); + return Center(child: Text(l10n.noTopicsFound)); } return PaginatedDataTable2( columns: [ - DataColumn2( - label: Text(l10n.topicName), - size: ColumnSize.L, - ), - DataColumn2( - label: Text(l10n.status), - size: ColumnSize.S, - ), - DataColumn2( - label: Text(l10n.lastUpdated), - size: ColumnSize.M, - ), + DataColumn2(label: Text(l10n.topicName), size: ColumnSize.L), + DataColumn2(label: Text(l10n.status), size: ColumnSize.S), + DataColumn2(label: Text(l10n.lastUpdated), size: ColumnSize.M), DataColumn2( label: Text(l10n.actions), size: ColumnSize.S, diff --git a/lib/dashboard/bloc/dashboard_bloc.dart b/lib/dashboard/bloc/dashboard_bloc.dart index 0eb8472..ecc61c7 100644 --- a/lib/dashboard/bloc/dashboard_bloc.dart +++ b/lib/dashboard/bloc/dashboard_bloc.dart @@ -1,7 +1,7 @@ import 'package:bloc/bloc.dart'; +import 'package:core/core.dart'; +import 'package:data_repository/data_repository.dart'; import 'package:equatable/equatable.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; part 'dashboard_event.dart'; part 'dashboard_state.dart'; @@ -10,16 +10,16 @@ part 'dashboard_state.dart'; class DashboardBloc extends Bloc { /// {@macro dashboard_bloc} DashboardBloc({ - required HtDataRepository dashboardSummaryRepository, - required HtDataRepository headlinesRepository, + required DataRepository dashboardSummaryRepository, + required DataRepository headlinesRepository, }) : _dashboardSummaryRepository = dashboardSummaryRepository, _headlinesRepository = headlinesRepository, super(const DashboardState()) { on(_onDashboardSummaryLoaded); } - final HtDataRepository _dashboardSummaryRepository; - final HtDataRepository _headlinesRepository; + final DataRepository _dashboardSummaryRepository; + final DataRepository _headlinesRepository; Future _onDashboardSummaryLoaded( DashboardSummaryLoaded event, @@ -28,10 +28,7 @@ class DashboardBloc extends Bloc { emit(state.copyWith(status: DashboardStatus.loading)); try { // Fetch summary and recent headlines concurrently - final [ - summaryResponse, - recentHeadlinesResponse, - ] = await Future.wait([ + final [summaryResponse, recentHeadlinesResponse] = await Future.wait([ _dashboardSummaryRepository.read(id: kDashboardSummaryId), _headlinesRepository.readAll( pagination: const PaginationOptions(limit: 5), @@ -49,13 +46,8 @@ class DashboardBloc extends Bloc { recentHeadlines: recentHeadlines, ), ); - } on HtHttpException catch (e) { - emit( - state.copyWith( - status: DashboardStatus.failure, - exception: e, - ), - ); + } on HttpException catch (e) { + emit(state.copyWith(status: DashboardStatus.failure, exception: e)); } catch (e) { emit( state.copyWith( diff --git a/lib/dashboard/bloc/dashboard_state.dart b/lib/dashboard/bloc/dashboard_state.dart index 25a48de..54578f5 100644 --- a/lib/dashboard/bloc/dashboard_state.dart +++ b/lib/dashboard/bloc/dashboard_state.dart @@ -27,13 +27,13 @@ final class DashboardState extends Equatable { final DashboardStatus status; final DashboardSummary? summary; final List recentHeadlines; - final HtHttpException? exception; + final HttpException? exception; DashboardState copyWith({ DashboardStatus? status, DashboardSummary? summary, List? recentHeadlines, - HtHttpException? exception, + HttpException? exception, }) { return DashboardState( status: status ?? this.status, @@ -44,10 +44,5 @@ final class DashboardState extends Equatable { } @override - List get props => [ - status, - summary, - recentHeadlines, - exception, - ]; + List get props => [status, summary, recentHeadlines, exception]; } diff --git a/lib/dashboard/view/dashboard_page.dart b/lib/dashboard/view/dashboard_page.dart index 2642081..bbceef5 100644 --- a/lib/dashboard/view/dashboard_page.dart +++ b/lib/dashboard/view/dashboard_page.dart @@ -1,11 +1,11 @@ +import 'package:core/core.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/dashboard/bloc/dashboard_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/router/routes.dart'; import 'package:go_router/go_router.dart'; -import 'package:ht_dashboard/dashboard/bloc/dashboard_bloc.dart'; -import 'package:ht_dashboard/l10n/l10n.dart'; -import 'package:ht_dashboard/router/routes.dart'; -import 'package:ht_shared/ht_shared.dart'; -import 'package:ht_ui_kit/ht_ui_kit.dart'; +import 'package:ui_kit/ui_kit.dart'; /// {@template dashboard_page} /// The main dashboard page, displaying key statistics and quick actions. diff --git a/lib/l10n/l10n.dart b/lib/l10n/l10n.dart index e0bd027..27bfd1b 100644 --- a/lib/l10n/l10n.dart +++ b/lib/l10n/l10n.dart @@ -1,5 +1,5 @@ import 'package:flutter/widgets.dart'; -import 'package:ht_dashboard/l10n/app_localizations.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/app_localizations.dart'; extension AppLocalizationsX on BuildContext { AppLocalizations get l10n => AppLocalizations.of(this); diff --git a/lib/main.dart b/lib/main.dart index 34b787b..340698d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,8 +2,8 @@ import 'dart:js_interop'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:ht_dashboard/app/config/config.dart'; -import 'package:ht_dashboard/bootstrap.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/app/config/config.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/bootstrap.dart'; // Define the current application environment (production/development/demo). const AppEnvironment appEnvironment = AppEnvironment.demo; diff --git a/lib/router/router.dart b/lib/router/router.dart index 60de487..942e7f7 100644 --- a/lib/router/router.dart +++ b/lib/router/router.dart @@ -1,25 +1,26 @@ +import 'package:auth_repository/auth_repository.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/app/bloc/app_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/app/config/config.dart' + as local_config; +import 'package:flutter_news_app_web_dashboard_full_source_code/app/view/app_shell.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/app_configuration/view/app_configuration_page.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/authentication/bloc/authentication_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/authentication/view/authentication_page.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/authentication/view/email_code_verification_page.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/authentication/view/request_code_page.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/view/content_management_page.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/view/create_headline_page.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/view/create_source_page.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/view/create_topic_page.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/view/edit_headline_page.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/view/edit_source_page.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/view/edit_topic_page.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/dashboard/view/dashboard_page.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/router/routes.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/settings/view/settings_page.dart'; import 'package:go_router/go_router.dart'; -import 'package:ht_auth_repository/ht_auth_repository.dart'; -import 'package:ht_dashboard/app/bloc/app_bloc.dart'; -import 'package:ht_dashboard/app/config/config.dart' as local_config; -import 'package:ht_dashboard/app/view/app_shell.dart'; -import 'package:ht_dashboard/app_configuration/view/app_configuration_page.dart'; -import 'package:ht_dashboard/authentication/bloc/authentication_bloc.dart'; -import 'package:ht_dashboard/authentication/view/authentication_page.dart'; -import 'package:ht_dashboard/authentication/view/email_code_verification_page.dart'; -import 'package:ht_dashboard/authentication/view/request_code_page.dart'; -import 'package:ht_dashboard/content_management/view/content_management_page.dart'; -import 'package:ht_dashboard/content_management/view/create_headline_page.dart'; -import 'package:ht_dashboard/content_management/view/create_source_page.dart'; -import 'package:ht_dashboard/content_management/view/create_topic_page.dart'; -import 'package:ht_dashboard/content_management/view/edit_headline_page.dart'; -import 'package:ht_dashboard/content_management/view/edit_source_page.dart'; -import 'package:ht_dashboard/content_management/view/edit_topic_page.dart'; -import 'package:ht_dashboard/dashboard/view/dashboard_page.dart'; -import 'package:ht_dashboard/router/routes.dart'; -import 'package:ht_dashboard/settings/view/settings_page.dart'; /// Creates and configures the GoRouter instance for the application. /// @@ -27,7 +28,7 @@ import 'package:ht_dashboard/settings/view/settings_page.dart'; /// authentication state changes. GoRouter createRouter({ required ValueNotifier authStatusNotifier, - required HtAuthRepository htAuthenticationRepository, + required AuthRepository authenticationRepository, required local_config.AppEnvironment environment, }) { return GoRouter( @@ -99,7 +100,7 @@ GoRouter createRouter({ builder: (BuildContext context, GoRouterState state) { return BlocProvider( create: (context) => AuthenticationBloc( - authenticationRepository: context.read(), + authenticationRepository: context.read(), ), child: const AuthenticationPage(), ); diff --git a/lib/settings/bloc/settings_bloc.dart b/lib/settings/bloc/settings_bloc.dart index 29a2c48..d7335cd 100644 --- a/lib/settings/bloc/settings_bloc.dart +++ b/lib/settings/bloc/settings_bloc.dart @@ -1,16 +1,16 @@ import 'dart:async'; import 'package:bloc/bloc.dart'; +import 'package:core/core.dart'; +import 'package:data_repository/data_repository.dart'; import 'package:equatable/equatable.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; part 'settings_event.dart'; part 'settings_state.dart'; class SettingsBloc extends Bloc { SettingsBloc({ - required HtDataRepository userAppSettingsRepository, + required DataRepository userAppSettingsRepository, }) : _userAppSettingsRepository = userAppSettingsRepository, super(const SettingsInitial()) { on(_onSettingsLoaded); @@ -22,7 +22,7 @@ class SettingsBloc extends Bloc { on(_onSettingsLanguageChanged); } - final HtDataRepository _userAppSettingsRepository; + final DataRepository _userAppSettingsRepository; Future _onSettingsLoaded( SettingsLoaded event, @@ -54,10 +54,8 @@ class SettingsBloc extends Bloc { ); await _userAppSettingsRepository.create(item: defaultSettings); emit(SettingsLoadSuccess(userAppSettings: defaultSettings)); - } on HtHttpException catch (e) { - emit( - SettingsLoadFailure(e, userAppSettings: state.userAppSettings), - ); + } on HttpException catch (e) { + emit(SettingsLoadFailure(e, userAppSettings: state.userAppSettings)); } catch (e) { emit( SettingsLoadFailure( @@ -79,13 +77,8 @@ class SettingsBloc extends Bloc { item: updatedSettings, ); emit(SettingsUpdateSuccess(userAppSettings: result)); - } on HtHttpException catch (e) { - emit( - SettingsUpdateFailure( - e, - userAppSettings: state.userAppSettings, - ), - ); + } on HttpException catch (e) { + emit(SettingsUpdateFailure(e, userAppSettings: state.userAppSettings)); } catch (e) { emit( SettingsUpdateFailure( diff --git a/lib/settings/bloc/settings_state.dart b/lib/settings/bloc/settings_state.dart index ab9de65..73ab964 100644 --- a/lib/settings/bloc/settings_state.dart +++ b/lib/settings/bloc/settings_state.dart @@ -42,7 +42,7 @@ final class SettingsLoadFailure extends SettingsState { const SettingsLoadFailure(this.exception, {super.userAppSettings}); /// The error exception describing the failure. - final HtHttpException exception; + final HttpException exception; @override List get props => [exception, userAppSettings]; @@ -72,7 +72,7 @@ final class SettingsUpdateFailure extends SettingsState { const SettingsUpdateFailure(this.exception, {super.userAppSettings}); /// The error exception describing the failure. - final HtHttpException exception; + final HttpException exception; @override List get props => [exception, userAppSettings]; diff --git a/lib/settings/view/settings_page.dart b/lib/settings/view/settings_page.dart index 42856c8..b1abec4 100644 --- a/lib/settings/view/settings_page.dart +++ b/lib/settings/view/settings_page.dart @@ -1,12 +1,12 @@ +import 'package:core/core.dart'; +import 'package:data_repository/data_repository.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:ht_dashboard/app/bloc/app_bloc.dart'; -import 'package:ht_dashboard/l10n/app_localizations.dart'; -import 'package:ht_dashboard/l10n/l10n.dart'; -import 'package:ht_dashboard/settings/bloc/settings_bloc.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; -import 'package:ht_ui_kit/ht_ui_kit.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/app/bloc/app_bloc.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/app_localizations.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/settings/bloc/settings_bloc.dart'; +import 'package:ui_kit/ui_kit.dart'; /// {@template settings_page} /// A page for user settings, allowing customization of theme and language. @@ -20,7 +20,7 @@ class SettingsPage extends StatelessWidget { return BlocProvider( create: (context) => SettingsBloc( userAppSettingsRepository: context - .read>(), + .read>(), )..add(SettingsLoaded(userId: context.read().state.user?.id)), child: const _SettingsView(), ); @@ -62,9 +62,7 @@ class _SettingsView extends StatelessWidget { ScaffoldMessenger.of(context) ..hideCurrentSnackBar() ..showSnackBar( - SnackBar( - content: Text(l10n.settingsSavedSuccessfully), - ), + SnackBar(content: Text(l10n.settingsSavedSuccessfully)), ); // Trigger AppBloc to reload settings for immediate UI update if (state.userAppSettings != null) { @@ -77,9 +75,7 @@ class _SettingsView extends StatelessWidget { ..hideCurrentSnackBar() ..showSnackBar( SnackBar( - content: Text( - state.exception.toFriendlyMessage(context), - ), + content: Text(state.exception.toFriendlyMessage(context)), ), ); } @@ -89,9 +85,7 @@ class _SettingsView extends StatelessWidget { state is! SettingsLoadInProgress) { // If settings are null and not loading, try to load them context.read().add( - SettingsLoaded( - userId: context.read().state.user?.id, - ), + SettingsLoaded(userId: context.read().state.user?.id), ); } @@ -138,9 +132,7 @@ class _SettingsView extends StatelessWidget { onChanged: (value) { if (value != null) { context.read().add( - SettingsBaseThemeChanged( - value, - ), + SettingsBaseThemeChanged(value), ); } }, @@ -149,10 +141,7 @@ class _SettingsView extends StatelessWidget { (theme) => DropdownMenuItem( value: theme, child: Text( - _getAppBaseThemeName( - theme, - l10n, - ), + _getAppBaseThemeName(theme, l10n), ), ), ) @@ -169,9 +158,7 @@ class _SettingsView extends StatelessWidget { onChanged: (value) { if (value != null) { context.read().add( - SettingsAccentThemeChanged( - value, - ), + SettingsAccentThemeChanged(value), ); } }, @@ -180,10 +167,7 @@ class _SettingsView extends StatelessWidget { (theme) => DropdownMenuItem( value: theme, child: Text( - _getAppAccentThemeName( - theme, - l10n, - ), + _getAppAccentThemeName(theme, l10n), ), ), ) @@ -207,9 +191,7 @@ class _SettingsView extends StatelessWidget { onChanged: (value) { if (value != null) { context.read().add( - SettingsFontFamilyChanged( - value, - ), + SettingsFontFamilyChanged(value), ); } }, @@ -217,12 +199,7 @@ class _SettingsView extends StatelessWidget { .map( (font) => DropdownMenuItem( value: font, - child: Text( - _getFontFamilyName( - font, - l10n, - ), - ), + child: Text(_getFontFamilyName(font, l10n)), ), ) .toList(), @@ -239,9 +216,7 @@ class _SettingsView extends StatelessWidget { onChanged: (value) { if (value != null) { context.read().add( - SettingsTextScaleFactorChanged( - value, - ), + SettingsTextScaleFactorChanged(value), ); } }, @@ -250,10 +225,7 @@ class _SettingsView extends StatelessWidget { (scale) => DropdownMenuItem( value: scale, child: Text( - _getAppTextScaleFactorName( - scale, - l10n, - ), + _getAppTextScaleFactorName(scale, l10n), ), ), ) @@ -270,9 +242,7 @@ class _SettingsView extends StatelessWidget { onChanged: (value) { if (value != null) { context.read().add( - SettingsFontWeightChanged( - value, - ), + SettingsFontWeightChanged(value), ); } }, @@ -281,10 +251,7 @@ class _SettingsView extends StatelessWidget { (weight) => DropdownMenuItem( value: weight, child: Text( - _getAppFontWeightName( - weight, - l10n, - ), + _getAppFontWeightName(weight, l10n), ), ), ) @@ -338,10 +305,7 @@ class _SettingsView extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - title, - style: Theme.of(context).textTheme.titleMedium, - ), + Text(title, style: Theme.of(context).textTheme.titleMedium), const SizedBox(height: AppSpacing.xs), Text( description, @@ -467,10 +431,7 @@ class _LanguageSelectionList extends StatelessWidget { style: Theme.of(context).textTheme.titleMedium, ), trailing: isSelected - ? Icon( - Icons.check, - color: Theme.of(context).colorScheme.primary, - ) + ? Icon(Icons.check, color: Theme.of(context).colorScheme.primary) : null, onTap: () { if (!isSelected) { @@ -495,8 +456,5 @@ class _LanguageSelectionList extends StatelessWidget { } } - static const List _supportedLanguages = [ - 'en', - 'ar', - ]; + static const List _supportedLanguages = ['en', 'ar']; } diff --git a/lib/shared/extensions/content_status_l10n.dart b/lib/shared/extensions/content_status_l10n.dart index 5a723d1..9b8b86c 100644 --- a/lib/shared/extensions/content_status_l10n.dart +++ b/lib/shared/extensions/content_status_l10n.dart @@ -1,6 +1,6 @@ +import 'package:core/core.dart'; import 'package:flutter/widgets.dart'; -import 'package:ht_dashboard/l10n/l10n.dart'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart'; /// Provides a localized string representation for [ContentStatus]. extension ContentStatusL10n on ContentStatus { diff --git a/pubspec.lock b/pubspec.lock index 296d295..64fc3a6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -9,6 +9,42 @@ packages: url: "https://pub.dev" source: hosted version: "2.13.0" + auth_api: + dependency: "direct main" + description: + path: "." + ref: HEAD + resolved-ref: "94cf789316c23569b7b7d641a5243848749aa079" + url: "https://github.com/flutter-news-app-full-source-code/auth-api.git" + source: git + version: "0.0.0" + auth_client: + dependency: "direct main" + description: + path: "." + ref: HEAD + resolved-ref: "8e331975e2df63e2eb6f06d9059309397375bb19" + url: "https://github.com/flutter-news-app-full-source-code/auth-client.git" + source: git + version: "0.0.0" + auth_inmemory: + dependency: "direct main" + description: + path: "." + ref: HEAD + resolved-ref: f48dc0555b1a28ed3c51215f3a93403dbbc46ea0 + url: "https://github.com/flutter-news-app-full-source-code/auth-inmemory" + source: git + version: "0.0.0" + auth_repository: + dependency: "direct main" + description: + path: "." + ref: HEAD + resolved-ref: "390e33098a8e6cbe30934386f4c0fe5b48783b0a" + url: "https://github.com/flutter-news-app-full-source-code/auth-repository.git" + source: git + version: "0.0.0" bloc: dependency: "direct main" description: @@ -49,6 +85,15 @@ packages: url: "https://pub.dev" source: hosted version: "1.19.1" + core: + dependency: "direct main" + description: + path: "." + ref: HEAD + resolved-ref: "3022edcb06d7c55ea81f25126b7f8c28c9105d4c" + url: "https://github.com/flutter-news-app-full-source-code/core.git" + source: git + version: "0.0.0" crypto: dependency: transitive description: @@ -57,6 +102,42 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.6" + data_api: + dependency: "direct main" + description: + path: "." + ref: HEAD + resolved-ref: "2b5691784f32b86e5c9d7d9999fa6dc11fb9a3a0" + url: "https://github.com/flutter-news-app-full-source-code/data-api.git" + source: git + version: "0.0.0" + data_client: + dependency: "direct main" + description: + path: "." + ref: HEAD + resolved-ref: "8800311dad6e94bff7fb7a738c8583483bee33ca" + url: "https://github.com/flutter-news-app-full-source-code/data-client.git" + source: git + version: "0.0.0" + data_inmemory: + dependency: "direct main" + description: + path: "." + ref: HEAD + resolved-ref: f12b8a78ee3ca0ca18b356e4c89f1d9171e2be61 + url: "https://github.com/flutter-news-app-full-source-code/data-inmemory.git" + source: git + version: "0.0.0" + data_repository: + dependency: "direct main" + description: + path: "." + ref: HEAD + resolved-ref: "5a7bd9f597e98209bc7f5ac897cf64552306c02f" + url: "https://github.com/flutter-news-app-full-source-code/data-repository.git" + source: git + version: "0.0.0" data_table_2: dependency: "direct main" description: @@ -200,123 +281,6 @@ packages: url: "https://pub.dev" source: hosted version: "6.2.1" - ht_auth_api: - dependency: "direct main" - description: - path: "." - ref: HEAD - resolved-ref: a2fc2a651494831a461fff96807141bdba9cc28b - url: "https://github.com/headlines-toolkit/ht-auth-api.git" - source: git - version: "0.0.0" - ht_auth_client: - dependency: "direct main" - description: - path: "." - ref: HEAD - resolved-ref: a003eb493db4fc134db419a721ee2fda0b598032 - url: "https://github.com/headlines-toolkit/ht-auth-client.git" - source: git - version: "0.0.0" - ht_auth_inmemory: - dependency: "direct main" - description: - path: "." - ref: HEAD - resolved-ref: ea9ad0361b1e0beab4690959889b7056091d29dc - url: "https://github.com/headlines-toolkit/ht-auth-inmemory" - source: git - version: "0.0.0" - ht_auth_repository: - dependency: "direct main" - description: - path: "." - ref: HEAD - resolved-ref: b7de5cc86d432b17710c83a1bf8de105bb4fa00d - url: "https://github.com/headlines-toolkit/ht-auth-repository.git" - source: git - version: "0.0.0" - ht_data_api: - dependency: "direct main" - description: - path: "." - ref: HEAD - resolved-ref: "16630c8717646663e52eee3ebedc4daa35ec4d39" - url: "https://github.com/headlines-toolkit/ht-data-api.git" - source: git - version: "0.0.0" - ht_data_client: - dependency: "direct main" - description: - path: "." - ref: HEAD - resolved-ref: e566ee6eae5261c00d0987972efc77a37a0c4c3a - url: "https://github.com/headlines-toolkit/ht-data-client.git" - source: git - version: "0.0.0" - ht_data_inmemory: - dependency: "direct main" - description: - path: "." - ref: HEAD - resolved-ref: abef81e5294d70ace82d3e87f1efc94fca6a8445 - url: "https://github.com/headlines-toolkit/ht-data-inmemory.git" - source: git - version: "0.0.0" - ht_data_repository: - dependency: "direct main" - description: - path: "." - ref: HEAD - resolved-ref: f19fe64c67a2febdef853b15f6df9c63240ad48e - url: "https://github.com/headlines-toolkit/ht-data-repository.git" - source: git - version: "0.0.0" - ht_http_client: - dependency: "direct main" - description: - path: "." - ref: HEAD - resolved-ref: "3c50cd082406d4cacafe60ad097ba6fa6ba891eb" - url: "https://github.com/headlines-toolkit/ht-http-client.git" - source: git - version: "0.0.0" - ht_kv_storage_service: - dependency: "direct main" - description: - path: "." - ref: HEAD - resolved-ref: "2378d6698df1cdeb7c5a17470f94fb8a5a99ca01" - url: "https://github.com/headlines-toolkit/ht-kv-storage-service.git" - source: git - version: "0.0.0" - ht_kv_storage_shared_preferences: - dependency: "direct main" - description: - path: "." - ref: HEAD - resolved-ref: "3c65be5424cfe155ec0f35f9a61ddf5c3bdae5cf" - url: "https://github.com/headlines-toolkit/ht-kv-storage-shared-preferences.git" - source: git - version: "0.0.0" - ht_shared: - dependency: "direct main" - description: - path: "." - ref: HEAD - resolved-ref: "2f78ac83c319242822250088c1edb11324404cb3" - url: "https://github.com/headlines-toolkit/ht-shared.git" - source: git - version: "0.0.0" - ht_ui_kit: - dependency: "direct main" - description: - path: "." - ref: HEAD - resolved-ref: "1c13e5accfa5fad7d262fbc5693780eac6f03fd9" - url: "https://github.com/headlines-toolkit/ht-ui-kit.git" - source: git - version: "0.0.0" http: dependency: transitive description: @@ -325,6 +289,15 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" + http_client: + dependency: "direct main" + description: + path: "." + ref: HEAD + resolved-ref: d4b48d57a441a12450724ff14a9796cc0f701754 + url: "https://github.com/flutter-news-app-full-source-code/http-client.git" + source: git + version: "0.0.0" http_parser: dependency: transitive description: @@ -349,6 +322,24 @@ packages: url: "https://pub.dev" source: hosted version: "4.9.0" + kv_storage_service: + dependency: "direct main" + description: + path: "." + ref: HEAD + resolved-ref: "9ab4ec1467a3e97303f26afe193d29a56e42a8f6" + url: "https://github.com/flutter-news-app-full-source-code/kv-storage-service.git" + source: git + version: "0.0.0" + kv_storage_shared_preferences: + dependency: "direct main" + description: + path: "." + ref: HEAD + resolved-ref: f39ef951681e27eadab926fdcf7ece8fc1319a05 + url: "https://github.com/flutter-news-app-full-source-code/kv-storage-shared-preferences.git" + source: git + version: "0.0.0" logging: dependency: "direct main" description: @@ -578,6 +569,15 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" + ui_kit: + dependency: "direct main" + description: + path: "." + ref: HEAD + resolved-ref: "21297142a410dd4e0b8af7aa16178ccb3fcdd867" + url: "https://github.com/flutter-news-app-full-source-code/ui-kit.git" + source: git + version: "0.0.0" uuid: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 4699a58..e1bccbe 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,14 +1,41 @@ -name: ht_dashboard -description: "A Flutter web application for comprehensive content management and administration within the Headlines Toolkit ecosystem." +name: flutter_news_app_web_dashboard_full_source_code +description: "A Flutter web application for comprehensive content management and administration within the Flutter News App Full Source Code Toolkit." publish_to: none -repository: https://github.com/headlines-toolkit/ht-dashboard +repository: https://github.com/flutter-news-app-full-source-code/flutter-news-app-web-dashboard-full-source-code environment: sdk: ^3.8.0 dependencies: + auth_api: + git: + url: https://github.com/flutter-news-app-full-source-code/auth-api.git + auth_client: + git: + url: https://github.com/flutter-news-app-full-source-code/auth-client.git + auth_inmemory: + git: + url: https://github.com/flutter-news-app-full-source-code/auth-inmemory + auth_repository: + git: + url: https://github.com/flutter-news-app-full-source-code/auth-repository.git bloc: ^9.0.0 bloc_concurrency: ^0.3.0 + core: + git: + url: https://github.com/flutter-news-app-full-source-code/core.git + data_api: + git: + url: https://github.com/flutter-news-app-full-source-code/data-api.git + data_client: + git: + url: https://github.com/flutter-news-app-full-source-code/data-client.git + data_inmemory: + git: + url: https://github.com/flutter-news-app-full-source-code/data-inmemory.git + data_repository: + git: + url: https://github.com/flutter-news-app-full-source-code/data-repository.git data_table_2: ^2.6.0 device_preview: ^1.2.0 equatable: ^2.0.7 @@ -21,48 +48,21 @@ dependencies: sdk: flutter go_router: ^16.0.0 google_fonts: ^6.2.1 - ht_auth_api: - git: - url: https://github.com/headlines-toolkit/ht-auth-api.git - ht_auth_client: - git: - url: https://github.com/headlines-toolkit/ht-auth-client.git - ht_auth_inmemory: + http_client: git: - url: https://github.com/headlines-toolkit/ht-auth-inmemory - ht_auth_repository: - git: - url: https://github.com/headlines-toolkit/ht-auth-repository.git - ht_data_api: - git: - url: https://github.com/headlines-toolkit/ht-data-api.git - ht_data_client: - git: - url: https://github.com/headlines-toolkit/ht-data-client.git - ht_data_inmemory: - git: - url: https://github.com/headlines-toolkit/ht-data-inmemory.git - ht_data_repository: - git: - url: https://github.com/headlines-toolkit/ht-data-repository.git - ht_http_client: - git: - url: https://github.com/headlines-toolkit/ht-http-client.git - ht_kv_storage_service: - git: - url: https://github.com/headlines-toolkit/ht-kv-storage-service.git - ht_kv_storage_shared_preferences: - git: - url: https://github.com/headlines-toolkit/ht-kv-storage-shared-preferences.git - ht_shared: + url: https://github.com/flutter-news-app-full-source-code/http-client.git + intl: ^0.20.2 + kv_storage_service: git: - url: https://github.com/headlines-toolkit/ht-shared.git - ht_ui_kit: + url: https://github.com/flutter-news-app-full-source-code/kv-storage-service.git + kv_storage_shared_preferences: git: - url: https://github.com/headlines-toolkit/ht-ui-kit.git - intl: ^0.20.2 + url: https://github.com/flutter-news-app-full-source-code/kv-storage-shared-preferences.git logging: ^1.3.0 timeago: ^3.7.1 + ui_kit: + git: + url: https://github.com/flutter-news-app-full-source-code/ui-kit.git uuid: ^4.5.1 diff --git a/web/index.html b/web/index.html index 73d218e..e05c73e 100644 --- a/web/index.html +++ b/web/index.html @@ -27,7 +27,7 @@ - Headlines Toolkit + Flutter News App Dashboard