Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
130 commits
Select commit Hold shift + click to select a range
4b987f6
feat(community): register new data repositories
fulleni Dec 1, 2025
99c2f06
feat(l10n): add community management translations
fulleni Dec 1, 2025
6d53c99
build(l10n): sync
fulleni Dec 1, 2025
ffd950b
feat(community): provide new repositories and BLoCs
fulleni Dec 1, 2025
8589096
feat(community): define community management route constant
fulleni Dec 1, 2025
73de080
feat(community): grant route permissions for admin
fulleni Dec 1, 2025
8112fe2
feat(community): add navigation destination to app shell
fulleni Dec 1, 2025
5f3e2a1
feat(community): configure community management route
fulleni Dec 1, 2025
d025bf7
feat(community): create community management bloc
fulleni Dec 1, 2025
05ab655
feat(community): create community management page shell
fulleni Dec 1, 2025
db078ff
feat(community_management): add engagements page
fulleni Dec 1, 2025
d242fbd
feat(community_management): add community action buttons widget
fulleni Dec 1, 2025
9ade0b4
feat(community_management): implement reports page
fulleni Dec 1, 2025
9518599
feat(community_management): add app reviews page
fulleni Dec 1, 2025
ddee43f
feat(community_management): implement CommunityFilterBloc
fulleni Dec 1, 2025
9fdbb18
feat(community_management): implement community filter dialog bloc
fulleni Dec 1, 2025
c952114
feat(community_management): add community filter dialog widget
fulleni Dec 1, 2025
e18dfdf
feat(community_management): add community management events
fulleni Dec 1, 2025
16703b9
feat(community_management): add CommunityManagementState class
fulleni Dec 1, 2025
5719aa8
feat(community_management): add community filter events
fulleni Dec 1, 2025
0f374d4
feat(community_management): add CommunityFilterState class
fulleni Dec 1, 2025
a411b19
feat(community_management): add community filter dialog events
fulleni Dec 1, 2025
34f0787
feat(lib): add CommunityFilterDialogState for community management
fulleni Dec 1, 2025
002ea2f
feat(router): add community filter dialog route
fulleni Dec 1, 2025
5f0f974
style: format
fulleni Dec 1, 2025
1d8cfa9
feat(community_management): enhance logging and error handling
fulleni Dec 1, 2025
4da7242
refactor(community_management): remove unused PendingDeletionsService
fulleni Dec 1, 2025
6516074
feat(localization): add generic 'Yes' and 'No' responses to Arabic an…
fulleni Dec 1, 2025
2c4d607
build(serialization): sync
fulleni Dec 1, 2025
a64b6e3
feat(l10n): add admin moderation and comment management translations
fulleni Dec 1, 2025
ebe1112
build(l10n): sync
fulleni Dec 1, 2025
88ae3d4
feat(l10n): add CommentStatus localization extension
fulleni Dec 1, 2025
bf57fb6
feat(l10n): add ReportStatus localization extension
fulleni Dec 1, 2025
a2d3210
feat(l10n): add ReportableEntity localization extension
fulleni Dec 1, 2025
1d00d0d
feat(l10n): add InitialAppReviewFeedback localization extension
fulleni Dec 1, 2025
9e97885
feat(l10n): add ReportReason localization extension
fulleni Dec 1, 2025
4d6cd7d
refactor(community): make CommunityActionButtons generic and add actions
fulleni Dec 1, 2025
5eeca5b
feat(community): refine EngagementsPage UI
fulleni Dec 1, 2025
5664e09
feat(community): refine ReportsPage UI
fulleni Dec 1, 2025
b198acc
feat(community): refine AppReviewsPage UI
fulleni Dec 1, 2025
6cd98be
feat(community): localize filter dialog dropdowns and update search hint
fulleni Dec 1, 2025
13cdf4a
refactor(community): remove redundant activeTab from CommunityFilterD…
fulleni Dec 1, 2025
2557304
refactor(router): remove unused repository arguments from communityFi…
fulleni Dec 1, 2025
7bbb08d
chore: barrels
fulleni Dec 1, 2025
87f2735
style: format
fulleni Dec 1, 2025
3a2e712
fix(localization): update ReportableEntity extension for consistency
fulleni Dec 1, 2025
7987bc9
feat(localization): add Arabic translation for "cancel" and remove un…
fulleni Dec 1, 2025
918513b
fix(community): implement navigation to reported items and update act…
fulleni Dec 1, 2025
8d45e1f
style: format
fulleni Dec 1, 2025
ca90fb2
build(pubspec): update core package reference
fulleni Dec 2, 2025
b26ef43
fix(community_management): update filter field for app review feedback
fulleni Dec 2, 2025
fec9c65
refactor(community_management): rename InitialAppReviewFeedback to Ap…
fulleni Dec 2, 2025
c901be4
refactor(community_management): update community filter dialog feedba…
fulleni Dec 2, 2025
de0c7b6
refactor(app-reviews): update feedback handling and UI
fulleni Dec 2, 2025
109e9fd
feat(l10n): add new community management translations
fulleni Dec 2, 2025
e3b55ea
feat(community_management): enhance data table columns and tooltips
fulleni Dec 2, 2025
c76ee91
feat(l10n): add Arabic and English translations for feedback feature
fulleni Dec 2, 2025
a949488
refactor(app_reviews_page): improve feedback display and table layout
fulleni Dec 2, 2025
bb23a63
feat(community_management): enhance engagements page with chips
fulleni Dec 2, 2025
fc3ed09
refactor.community_management: improve visual representation of reports
fulleni Dec 2, 2025
25d8680
feat(community): add copy user ID action and improve feedback details
fulleni Dec 2, 2025
fdf9ee3
refactor(localization): simplify comment rejection confirmation messages
fulleni Dec 2, 2025
af6eb53
refactor: simplify search hint in community filter dialog
fulleni Dec 2, 2025
9356ccc
fix(community): Remove regex for exact match in user search
fulleni Dec 2, 2025
cca1e53
refactor(community_management): update comment display in engagements…
fulleni Dec 2, 2025
06763a2
refactor(community_management): remove comment update functionality
fulleni Dec 2, 2025
bcb9bdf
feat(bloc): add filter map building functionality to multiple blocs
fulleni Dec 2, 2025
861ad20
fix(localization): update search placeholder text in Arabic and English
fulleni Dec 2, 2025
f4a01ea
refactor(layout): improve responsive design for app reviews and commu…
fulleni Dec 2, 2025
0bf26c5
build(deps): update core package to latest version
fulleni Dec 2, 2025
2d9156a
refactor(shared): remove unused extensions
fulleni Dec 2, 2025
5dc6789
refactor(l10n): rename comment and report statuses to moderation stat…
fulleni Dec 2, 2025
82ae068
build(l10n): sync
fulleni Dec 2, 2025
e1d59bf
refactor(community): align filter state with ModerationStatus
fulleni Dec 2, 2025
5881c6e
refactor(community): align filter event with ModerationStatus
fulleni Dec 2, 2025
3662354
refactor(community): align filter state with ModerationStatus
fulleni Dec 2, 2025
dfa0b48
refactor(community): align filter dialog state with ModerationStatus
fulleni Dec 2, 2025
07a1316
refactor(community): consolidate filter dialog events for ModerationS…
fulleni Dec 2, 2025
d763a55
refactor(community): update filter dialog bloc to use ModerationStatus
fulleni Dec 2, 2025
a8a5f6a
feat(community): implement capsule list for status filtering
fulleni Dec 2, 2025
45bc81b
refactor(community): adapt moderation actions to new status model
fulleni Dec 2, 2025
5fe551a
fix(community): update engagements table UI for new moderation status
fulleni Dec 2, 2025
6039e64
refactor(community): update filter bloc to use ModerationStatus
fulleni Dec 2, 2025
fac2d99
fix(community): update reports table UI for new moderation status
fulleni Dec 2, 2025
c0886bf
feat(community): enhance app review feedback visuals
fulleni Dec 2, 2025
8e9be13
fix(community_management): correct filter check for moderation status
fulleni Dec 2, 2025
b654553
feat(extension): add moderation status localization
fulleni Dec 2, 2025
1c033e1
feat(community_management): enhance community filter dialog theming
fulleni Dec 2, 2025
15c34cf
style: format
fulleni Dec 2, 2025
344e2af
feat(l10n): add filter options for comments in Arabic and English
fulleni Dec 2, 2025
eb1fad4
feat(community_management): enhance comment and report filtering
fulleni Dec 2, 2025
408152d
feat(community_management): enhance community filter dialog
fulleni Dec 2, 2025
68a95eb
fix(community_management): update filter logic for engagements and re…
fulleni Dec 2, 2025
6d7da60
fix(community_management): improve filter logic for comments and reports
fulleni Dec 2, 2025
96cd5b0
fix(community_management): resolve comment by removing it
fulleni Dec 2, 2025
ec21557
refactor(community_management): improve filter dialog functionality
fulleni Dec 2, 2025
5ad6f08
refactor(community_management): split CommunityFilterState and improv…
fulleni Dec 2, 2025
a2a212c
fix(community_management): prevent duplicate API calls when filters a…
fulleni Dec 2, 2025
3cbb39f
feat(community_management): add 'any' option to multi select chips
fulleni Dec 2, 2025
ca81fef
feat(community_management): enhance community filter dialog
fulleni Dec 2, 2025
2cdcf07
refactor(community_management): improve entity update handling
fulleni Dec 2, 2025
67a493e
chore: delete absolete file
fulleni Dec 2, 2025
6219e72
refactor(community_management): simplify community filterBloc
fulleni Dec 2, 2025
a7a347a
refactor(community_management): improve filter handling and update logic
fulleni Dec 2, 2025
756cf1f
refactor(community_management): improve filter handling in multiple p…
fulleni Dec 2, 2025
b4894c3
refactor(router): remove bloc from community filter dialog
fulleni Dec 2, 2025
666b376
refactor(community_management): restructure community filter function…
fulleni Dec 2, 2025
26ebc5c
refactor(community_management): improve filter handling and code stru…
fulleni Dec 2, 2025
077908b
refactor(community_management): improve filter dialog functionality
fulleni Dec 2, 2025
db586b9
fix(l10n): reorganize and add report resolved localization entries
fulleni Dec 2, 2025
bfd14fa
feat(community_management): implement pending updates and improve UI
fulleni Dec 2, 2025
f67f8a8
refactor(community_management): improve code structure and remove des…
fulleni Dec 2, 2025
4611203
feat(community_management): add details dialogs for app reviews, enga…
fulleni Dec 2, 2025
a2ae608
feat(shared): add pending updates service
fulleni Dec 2, 2025
3f14349
refactor(community_management): update action buttons and remove BLoC
fulleni Dec 2, 2025
911ad6d
feat(l10n): add translations for report and comment details
fulleni Dec 2, 2025
e84756f
refactor(dialogs): simplify content and update localizations
fulleni Dec 2, 2025
1879103
feat(community_management): replace more_horiz icon with comment_outl…
fulleni Dec 2, 2025
477e29d
style: add background color to entity type chip
fulleni Dec 2, 2025
7bfba86
feat(community_management): add background colors to reaction chips
fulleni Dec 2, 2025
e667796
feat(ui): enhance visual distinction of report entity types
fulleni Dec 2, 2025
c9cf9e3
feat(dialog): improve layout and styling of detail dialogs
fulleni Dec 2, 2025
b7660d9
fix(communities): make feedback details button always clickable
fulleni Dec 2, 2025
5bcf208
refactor(l10n): improve community management localization
fulleni Dec 2, 2025
eb9699e
fix(localization): update navigation label localization
fulleni Dec 2, 2025
b7a74e9
feat(README): add community & moderation control section
fulleni Dec 2, 2025
f87e940
style: format
fulleni Dec 2, 2025
952bc6e
fix(community_management): handle null pending update id
fulleni Dec 2, 2025
371dcac
fix(community_management): implement workaround for Engagement commen…
fulleni Dec 2, 2025
81f3ef4
style: fix typo in TODO comment
fulleni Dec 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ Effortlessly manage your entire user base with a dedicated user management syste

</details>

<details>
<summary><strong>💬 Community & Moderation Control</strong></summary>

### 💬 Comprehensive Moderation Hub
Directly manage all user-generated content from a centralized command center. Review, moderate, and act on user interactions to maintain a healthy and constructive community environment.
- **Unified Content Review:** Seamlessly moderate all incoming user engagements (reactions and comments), content reports, and app review feedback from a single, intuitive interface.
- **Streamlined Moderation Workflow:** Quickly approve or reject comments, resolve user-submitted reports, and analyze feedback with a consistent set of tools designed for rapid decision-making.
- **Direct User Insight:** Gain a clear, unfiltered view of user sentiment, content issues, and overall satisfaction by directly engaging with their feedback and reports.
> **Your Advantage:** Foster a positive community, protect your brand by quickly addressing problematic content, and gather valuable user insights to improve your content strategy, all from one integrated hub.

</details>


<details>
<summary><strong>⚙️ App Monetization & Remote Control</strong></summary>
Expand All @@ -62,6 +74,7 @@ Dynamically control the mobile app's behavior and operational state directly fro
- **Critical State Management:** Instantly activate a maintenance mode or enforce a mandatory app update for your users to handle operational issues or critical releases gracefully.
- **Dynamic In-App Content:** Remotely manage the visibility and behavior of in-feed promotional prompts and user engagement elements.
- **Tier-Based Feature Gating:** Define and enforce feature limits based on user roles, such as setting the maximum number of followed topics or saved headlines for different subscription levels.
- **Full Community Feature Control:** Remotely enable or disable the entire user engagement system (reactions, comments), the content reporting feature, and the in-app review funnel. Fine-tune engagement modes and configure rules for when and how users are prompted for feedback.
- **Global Notification Control:** Remotely enable or disable the entire push notification system, switch between providers (e.g., Firebase, OneSignal), and toggle specific delivery types like breaking news or daily digests.
> **Your Advantage:** Gain unparalleled agility to manage your live application. Ensure service stability, drive user actions, and configure business rules instantly, all from a centralized control panel.

Expand Down
30 changes: 30 additions & 0 deletions lib/app/view/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import 'package:flutter_news_app_web_dashboard_full_source_code/app/bloc/app_blo
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/community_management/bloc/community_filter/community_filter_bloc.dart';
import 'package:flutter_news_app_web_dashboard_full_source_code/community_management/bloc/community_management_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/headlines_filter/headlines_filter_bloc.dart';
import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/bloc/sources_filter/sources_filter_bloc.dart';
Expand All @@ -19,6 +21,7 @@ import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/app_localiz
import 'package:flutter_news_app_web_dashboard_full_source_code/overview/bloc/overview_bloc.dart';
import 'package:flutter_news_app_web_dashboard_full_source_code/router/router.dart';
import 'package:flutter_news_app_web_dashboard_full_source_code/shared/services/pending_deletions_service.dart';
import 'package:flutter_news_app_web_dashboard_full_source_code/shared/services/pending_updates_service.dart';
import 'package:flutter_news_app_web_dashboard_full_source_code/shared/shared.dart';
import 'package:flutter_news_app_web_dashboard_full_source_code/user_management/bloc/user_filter/user_filter_bloc.dart';
import 'package:flutter_news_app_web_dashboard_full_source_code/user_management/bloc/user_management_bloc.dart';
Expand All @@ -41,6 +44,9 @@ class App extends StatelessWidget {
required DataRepository<Country> countriesRepository,
required DataRepository<Language> languagesRepository,
required DataRepository<User> usersRepository,
required DataRepository<Engagement> engagementsRepository,
required DataRepository<Report> reportsRepository,
required DataRepository<AppReview> appReviewsRepository,
required KVStorageService storageService,
required AppEnvironment environment,
required PendingDeletionsService pendingDeletionsService,
Expand All @@ -57,6 +63,9 @@ class App extends StatelessWidget {
_countriesRepository = countriesRepository,
_languagesRepository = languagesRepository,
_usersRepository = usersRepository,
_engagementsRepository = engagementsRepository,
_reportsRepository = reportsRepository,
_appReviewsRepository = appReviewsRepository,
_environment = environment,
_pendingDeletionsService = pendingDeletionsService;

Expand All @@ -72,6 +81,9 @@ class App extends StatelessWidget {
final DataRepository<Country> _countriesRepository;
final DataRepository<Language> _languagesRepository;
final DataRepository<User> _usersRepository;
final DataRepository<Engagement> _engagementsRepository;
final DataRepository<Report> _reportsRepository;
final DataRepository<AppReview> _appReviewsRepository;
final KVStorageService _kvStorageService;
final AppEnvironment _environment;

Expand All @@ -93,13 +105,19 @@ class App extends StatelessWidget {
RepositoryProvider.value(value: _countriesRepository),
RepositoryProvider.value(value: _languagesRepository),
RepositoryProvider.value(value: _usersRepository),
RepositoryProvider.value(value: _engagementsRepository),
RepositoryProvider.value(value: _reportsRepository),
RepositoryProvider.value(value: _appReviewsRepository),
RepositoryProvider.value(value: _kvStorageService),
RepositoryProvider(
create: (context) => const ThrottledFetchingService(),
),
RepositoryProvider.value(
value: _pendingDeletionsService,
),
RepositoryProvider<PendingUpdatesService>(
create: (context) => PendingUpdatesServiceImpl(),
),
],
child: MultiBlocProvider(
providers: [
Expand Down Expand Up @@ -163,6 +181,18 @@ class App extends StatelessWidget {
userFilterBloc: context.read<UserFilterBloc>(),
),
),
BlocProvider(
create: (context) => CommunityFilterBloc(),
),
BlocProvider(
create: (context) => CommunityManagementBloc(
engagementsRepository: context.read<DataRepository<Engagement>>(),
reportsRepository: context.read<DataRepository<Report>>(),
appReviewsRepository: context.read<DataRepository<AppReview>>(),
communityFilterBloc: context.read<CommunityFilterBloc>(),
pendingUpdatesService: context.read<PendingUpdatesService>(),
),
),
],
child: _AppView(
authenticationRepository: _authenticationRepository,
Expand Down
10 changes: 8 additions & 2 deletions lib/app/view/app_shell.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,17 @@ class AppShell extends StatelessWidget {
NavigationDestination(
icon: const Icon(Icons.folder_open_outlined),
selectedIcon: const Icon(Icons.folder),
label: l10n.contentManagement,
label: l10n.navContent,
),
NavigationDestination(
icon: const Icon(Icons.people_outline),
selectedIcon: const Icon(Icons.people),
label: l10n.userManagement,
label: l10n.navUsers,
),
NavigationDestination(
icon: const Icon(Icons.forum_outlined),
selectedIcon: const Icon(Icons.forum),
label: l10n.navCommunity,
),
NavigationDestination(
icon: const Icon(Icons.settings_applications_outlined),
Expand All @@ -64,6 +69,7 @@ class AppShell extends StatelessWidget {
Routes.overviewName,
Routes.contentManagementName,
Routes.userManagementName,
Routes.communityManagementName,
Routes.appConfigurationName,
];

Expand Down
28 changes: 20 additions & 8 deletions lib/app_configuration/widgets/app_review_settings_form.dart
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,12 @@ class _AppReviewSettingsFormState extends State<AppReviewSettingsForm> {
padding: const EdgeInsetsDirectional.only(
start: AppSpacing.lg,
),
child: Column(
children: [
ExpansionTile(
child: LayoutBuilder(
builder: (context, constraints) {
final isMobile = constraints.maxWidth < 600;
return ExpansionTile(
title: Text(l10n.internalPromptLogicTitle),
initiallyExpanded: !isMobile,
childrenPadding: const EdgeInsetsDirectional.only(
start: AppSpacing.lg,
top: AppSpacing.md,
Expand Down Expand Up @@ -162,10 +164,20 @@ class _AppReviewSettingsFormState extends State<AppReviewSettingsForm> {
controller: _initialPromptCooldownController,
),
],
),
const SizedBox(height: AppSpacing.lg),
ExpansionTile(
);
},
),
),
Padding(
padding: const EdgeInsetsDirectional.only(
start: AppSpacing.lg,
),
child: LayoutBuilder(
builder: (context, constraints) {
final isMobile = constraints.maxWidth < 600;
return ExpansionTile(
title: Text(l10n.followUpActionsTitle),
initiallyExpanded: !isMobile,
childrenPadding: const EdgeInsetsDirectional.only(
start: AppSpacing.lg,
top: AppSpacing.md,
Expand Down Expand Up @@ -220,8 +232,8 @@ class _AppReviewSettingsFormState extends State<AppReviewSettingsForm> {
},
),
],
),
],
);
},
),
),
],
Expand Down
54 changes: 54 additions & 0 deletions lib/bootstrap.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ Future<Widget> bootstrap(
DataClient<Country> countriesClient;
DataClient<Language> languagesClient;
DataClient<User> usersClient;
DataClient<Engagement> engagementsClient;
DataClient<Report> reportsClient;
DataClient<AppReview> appReviewsClient;

if (appConfig.environment == app_config.AppEnvironment.demo) {
headlinesClient = DataInMemory<Headline>(
Expand Down Expand Up @@ -128,6 +131,24 @@ Future<Widget> bootstrap(
initialData: usersFixturesData,
logger: Logger('DataInMemory<User>'),
);
engagementsClient = DataInMemory<Engagement>(
toJson: (i) => i.toJson(),
getId: (i) => i.id,
initialData: getEngagementsFixturesData(),
logger: Logger('DataInMemory<Engagement>'),
);
reportsClient = DataInMemory<Report>(
toJson: (i) => i.toJson(),
getId: (i) => i.id,
initialData: getReportsFixturesData(),
logger: Logger('DataInMemory<Report>'),
);
appReviewsClient = DataInMemory<AppReview>(
toJson: (i) => i.toJson(),
getId: (i) => i.id,
initialData: getAppReviewsFixturesData(),
logger: Logger('DataInMemory<AppReview>'),
);
} else {
headlinesClient = DataApi<Headline>(
httpClient: httpClient!,
Expand Down Expand Up @@ -200,6 +221,27 @@ Future<Widget> bootstrap(
toJson: (user) => user.toJson(),
logger: Logger('DataApi<User>'),
);
engagementsClient = DataApi<Engagement>(
httpClient: httpClient,
modelName: 'engagement',
fromJson: Engagement.fromJson,
toJson: (engagement) => engagement.toJson(),
logger: Logger('DataApi<Engagement>'),
);
reportsClient = DataApi<Report>(
httpClient: httpClient,
modelName: 'report',
fromJson: Report.fromJson,
toJson: (report) => report.toJson(),
logger: Logger('DataApi<Report>'),
);
appReviewsClient = DataApi<AppReview>(
httpClient: httpClient,
modelName: 'app_review',
fromJson: AppReview.fromJson,
toJson: (appReview) => appReview.toJson(),
logger: Logger('DataApi<AppReview>'),
);
}

pendingDeletionsService = PendingDeletionsServiceImpl(
Expand Down Expand Up @@ -231,6 +273,15 @@ Future<Widget> bootstrap(
dataClient: languagesClient,
);
final usersRepository = DataRepository<User>(dataClient: usersClient);
final engagementsRepository = DataRepository<Engagement>(
dataClient: engagementsClient,
);
final reportsRepository = DataRepository<Report>(
dataClient: reportsClient,
);
final appReviewsRepository = DataRepository<AppReview>(
dataClient: appReviewsClient,
);

return App(
authenticationRepository: authenticationRepository,
Expand All @@ -244,6 +295,9 @@ Future<Widget> bootstrap(
countriesRepository: countriesRepository,
languagesRepository: languagesRepository,
usersRepository: usersRepository,
engagementsRepository: engagementsRepository,
reportsRepository: reportsRepository,
appReviewsRepository: appReviewsRepository,
storageService: kvStorage,
environment: environment,
pendingDeletionsService: pendingDeletionsService,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import 'package:bloc/bloc.dart';
import 'package:core/core.dart';
import 'package:equatable/equatable.dart';

part 'community_filter_event.dart';
part 'community_filter_state.dart';

class CommunityFilterBloc
extends Bloc<CommunityFilterEvent, CommunityFilterState> {
CommunityFilterBloc() : super(const CommunityFilterState()) {
on<EngagementsFilterChanged>(
(event, emit) => emit(
state.copyWith(
engagementsFilter: event.filter,
version: state.version,
),
),
);
on<ReportsFilterChanged>(
(event, emit) => emit(
state.copyWith(
reportsFilter: event.filter,
version: state.version,
),
),
);
on<AppReviewsFilterChanged>(
(event, emit) => emit(
state.copyWith(
appReviewsFilter: event.filter,
version: state.version,
),
),
);
on<CommunityFilterReset>(_onFilterReset);
on<CommunityFilterApplied>(_onFilterApplied);
}

void _onFilterReset(
CommunityFilterReset event,
Emitter<CommunityFilterState> emit,
) {
emit(const CommunityFilterState());
}

void _onFilterApplied(
CommunityFilterApplied event,
Emitter<CommunityFilterState> emit,
) {
emit(state.copyWith(version: state.version + 1));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
part of 'community_filter_bloc.dart';

abstract class CommunityFilterEvent extends Equatable {
const CommunityFilterEvent();

@override
List<Object> get props => [];
}

class EngagementsFilterChanged extends CommunityFilterEvent {
const EngagementsFilterChanged(this.filter);

final EngagementsFilter filter;

@override
List<Object> get props => [filter];
}

class ReportsFilterChanged extends CommunityFilterEvent {
const ReportsFilterChanged(this.filter);

final ReportsFilter filter;

@override
List<Object> get props => [filter];
}

class AppReviewsFilterChanged extends CommunityFilterEvent {
const AppReviewsFilterChanged(this.filter);

final AppReviewsFilter filter;

@override
List<Object> get props => [filter];
}

class CommunityFilterApplied extends CommunityFilterEvent {
const CommunityFilterApplied();
}

class CommunityFilterReset extends CommunityFilterEvent {
const CommunityFilterReset();
}
Loading
Loading