Skip to content

Commit 7ab953d

Browse files
authored
feat(cat-voices): workspace filtering and tabs (#3765)
* feat: adding translations * chore: update workspace page * chore: update user proposals * feat: workspace proposal filter * chore: adding new implemention of proposal brief * feat: workspace proposal tab * feat: adding new proposal invites * chore: move widgets in widget dir * feat: adding empty state for proposal invites * feat: updating filters * feat: updating filters options * feat: proposal invites count * fix: spelling * chore: review update * feat: adding new options to filters and brief data * feat(cat-voices): Using new stream source for WorkspaceBloc (#3785) * feat: working integration * chore: use bloc instead of cubit * chore: final changes * chore: selfreview * feat: review update * fix: readme * chore: rename factory constructor * feat: merge collaborators status enum into one * fix: format
1 parent 137a065 commit 7ab953d

File tree

45 files changed

+1595
-868
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1595
-868
lines changed

β€Žcatalyst_voices/README.mdβ€Ž

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ This repository contains the Catalyst Voices app and packages.
2222
* [Using Feature Flags with --dart-define](#using-feature-flags-with---dart-define)
2323
* [Code Generation](#code-generation)
2424
* [Running Code Generation](#running-code-generation)
25-
* [Basic Generation](#basic-generation)
26-
* [Local Saving](#local-saving)
27-
* [GitHub Token / PAT Setup](#github-token--pat-setup)
28-
* [Security Notes](#security-notes)
25+
* [Code Generation](#code-generation)
26+
*[Running Code Generation](#running-code-generation)
27+
* [Basic Generation](#basic-generation)
28+
*[Local Saving](#local-saving)
29+
* [GitHub Token / PAT Setup](#github-token--pat-setup)
30+
* [Security Notes](#security-notes)
2931
* [Running Tests](#running-tests)
3032

3133
## Requirements

β€Žcatalyst_voices/apps/voices/lib/dependency/dependencies.dartβ€Ž

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ final class Dependencies extends DependencyProvider {
130130
)
131131
..registerFactory<WorkspaceBloc>(() {
132132
return WorkspaceBloc(
133+
get<UserService>(),
133134
get<CampaignService>(),
134135
get<ProposalService>(),
135136
get<DocumentMapper>(),

β€Žcatalyst_voices/apps/voices/lib/pages/overall_spaces/space/user_proposal_overview/widgets/error_user_proposal_overview.dartβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class _Error extends StatelessWidget {
3333
padding: const EdgeInsets.only(top: 60),
3434
child: VoicesErrorIndicator(
3535
message: error?.message(context) ?? const LocalizedUnknownException().message(context),
36-
onRetry: () => context.read<WorkspaceBloc>().add(const WatchUserProposalsEvent()),
36+
onRetry: () => context.read<WorkspaceBloc>().add(const ChangeWorkspaceFilters()),
3737
),
3838
);
3939
}

β€Žcatalyst_voices/apps/voices/lib/pages/overall_spaces/spaces_overview_list_view.dartβ€Ž

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'package:catalyst_voices/widgets/containers/grey_out_container.dart';
77
import 'package:catalyst_voices/widgets/widgets.dart';
88
import 'package:catalyst_voices_blocs/catalyst_voices_blocs.dart';
99
import 'package:catalyst_voices_models/catalyst_voices_models.dart';
10+
import 'package:catalyst_voices_view_models/catalyst_voices_view_models.dart';
1011
import 'package:flutter/material.dart';
1112

1213
class SpacesListView extends StatefulWidget {
@@ -73,6 +74,11 @@ class _SpacesListViewState extends State<SpacesListView> {
7374
@override
7475
void initState() {
7576
super.initState();
76-
context.read<WorkspaceBloc>().add(const WatchUserProposalsEvent());
77+
context.read<WorkspaceBloc>().add(
78+
const ChangeWorkspaceFilters(
79+
filters: WorkspaceFilters.allProposals,
80+
tab: WorkspacePageTab.proposals,
81+
),
82+
);
7783
}
7884
}

β€Žcatalyst_voices/apps/voices/lib/pages/proposal/widget/proposal_collaborators.dartβ€Ž

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class _Collaborator extends StatelessWidget {
7676
}
7777

7878
class _Status extends StatelessWidget {
79-
final CollaboratorInvitationStatus status;
79+
final ProposalsCollaborationStatus status;
8080

8181
const _Status({required this.status});
8282

@@ -103,7 +103,7 @@ class _Status extends StatelessWidget {
103103

104104
class _Username extends StatelessWidget {
105105
final CatalystId catalystId;
106-
final CollaboratorInvitationStatus status;
106+
final ProposalsCollaborationStatus status;
107107

108108
const _Username({
109109
required this.catalystId,

β€Žcatalyst_voices/apps/voices/lib/pages/workspace/page/workspace_error.dartβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class _WorkspaceError extends StatelessWidget {
3838
child: VoicesErrorIndicator(
3939
message: message,
4040
onRetry: () {
41-
const event = WatchUserProposalsEvent();
41+
const event = ChangeWorkspaceFilters();
4242
context.read<WorkspaceBloc>().add(event);
4343
},
4444
),

β€Žcatalyst_voices/apps/voices/lib/pages/workspace/page/workspace_page.dartβ€Ž

Lines changed: 70 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,49 +3,56 @@ import 'dart:async';
33
import 'package:catalyst_voices/common/error_handler.dart';
44
import 'package:catalyst_voices/common/signal_handler.dart';
55
import 'package:catalyst_voices/pages/campaign_phase_aware/proposal_submission_phase_aware.dart';
6-
import 'package:catalyst_voices/pages/workspace/header/workspace_header.dart';
76
import 'package:catalyst_voices/pages/workspace/page/workspace_error.dart';
87
import 'package:catalyst_voices/pages/workspace/page/workspace_loading.dart';
9-
import 'package:catalyst_voices/pages/workspace/page/workspace_user_proposals.dart';
108
import 'package:catalyst_voices/pages/workspace/submission_closing_warning_dialog.dart';
9+
import 'package:catalyst_voices/pages/workspace/widgets/header/workspace_header.dart';
10+
import 'package:catalyst_voices/pages/workspace/widgets/workspace_content.dart';
1111
import 'package:catalyst_voices/routes/routing/proposal_builder_route.dart';
12+
import 'package:catalyst_voices/routes/routing/spaces_route.dart';
1213
import 'package:catalyst_voices/widgets/snackbar/common_snackbars.dart';
1314
import 'package:catalyst_voices/widgets/snackbar/voices_snackbar.dart';
1415
import 'package:catalyst_voices/widgets/snackbar/voices_snackbar_type.dart';
16+
import 'package:catalyst_voices/widgets/tabbar/voices_tab_controller.dart';
1517
import 'package:catalyst_voices_blocs/catalyst_voices_blocs.dart';
1618
import 'package:catalyst_voices_localization/catalyst_voices_localization.dart';
1719
import 'package:catalyst_voices_view_models/catalyst_voices_view_models.dart';
1820
import 'package:flutter/material.dart';
1921

2022
class WorkspacePage extends StatefulWidget {
21-
const WorkspacePage({super.key});
23+
final WorkspacePageTab? tab;
24+
25+
const WorkspacePage({super.key, this.tab});
2226

2327
@override
2428
State<WorkspacePage> createState() => _WorkspacePageState();
2529
}
2630

2731
class _WorkspacePageState extends State<WorkspacePage>
2832
with
33+
TickerProviderStateMixin,
2934
SignalHandlerStateMixin<WorkspaceBloc, WorkspaceSignal, WorkspacePage>,
3035
ErrorHandlerStateMixin<WorkspaceBloc, WorkspacePage> {
36+
late final VoicesTabController<WorkspacePageTab> _tabController;
37+
3138
@override
3239
Widget build(BuildContext context) {
33-
return const ProposalSubmissionPhaseAware(
40+
return ProposalSubmissionPhaseAware(
3441
activeChild: Scaffold(
3542
body: WorkspaceLoading(
3643
child: CustomScrollView(
3744
slivers: [
38-
SliverToBoxAdapter(
45+
const SliverToBoxAdapter(
3946
child: SizedBox(height: 10),
4047
),
41-
SliverToBoxAdapter(
48+
const SliverToBoxAdapter(
4249
child: WorkspaceHeader(),
4350
),
44-
SliverToBoxAdapter(
51+
const SliverToBoxAdapter(
4552
child: WorkspaceError(),
4653
),
47-
WorkspaceUserProposals(),
48-
SliverToBoxAdapter(
54+
WorkspaceContent(tabController: _tabController),
55+
const SliverToBoxAdapter(
4956
child: SizedBox(height: 50),
5057
),
5158
],
@@ -55,6 +62,26 @@ class _WorkspacePageState extends State<WorkspacePage>
5562
);
5663
}
5764

65+
@override
66+
void didUpdateWidget(WorkspacePage oldWidget) {
67+
super.didUpdateWidget(oldWidget);
68+
69+
final tab = widget.tab ?? WorkspacePageTab.proposals;
70+
71+
if (widget.tab != oldWidget.tab) {
72+
_tabController.animateToTab(tab);
73+
context.read<WorkspaceBloc>().add(
74+
ChangeWorkspaceFilters(tab: tab),
75+
);
76+
}
77+
}
78+
79+
@override
80+
void dispose() {
81+
_tabController.dispose();
82+
super.dispose();
83+
}
84+
5885
@override
5986
void handleError(Object error) {
6087
if (error is LocalizedProposalDeletionException) {
@@ -67,6 +94,8 @@ class _WorkspacePageState extends State<WorkspacePage>
6794
@override
6895
void handleSignal(WorkspaceSignal signal) {
6996
switch (signal) {
97+
case ChangeTabWorkspaceSignal(:final tab):
98+
_updateRoute(tab: tab);
7099
case ImportedProposalWorkspaceSignal():
71100
unawaited(
72101
ProposalBuilderRoute.fromRef(ref: signal.proposalRef).push(context),
@@ -87,13 +116,29 @@ class _WorkspacePageState extends State<WorkspacePage>
87116
@override
88117
void initState() {
89118
super.initState();
90-
final bloc = context.read<WorkspaceBloc>();
91-
// ignore: cascade_invocations
92-
bloc
93-
..add(const WatchUserProposalsEvent())
119+
final selectedTab = _determineTab(widget.tab);
120+
121+
_tabController = VoicesTabController(
122+
initialTab: selectedTab,
123+
tabs: WorkspacePageTab.values,
124+
vsync: this,
125+
);
126+
127+
_tabController.addListener(() {
128+
context.read<WorkspaceBloc>().add(
129+
ChangeWorkspaceFilters(tab: _tabController.tab),
130+
);
131+
});
132+
133+
context.read<WorkspaceBloc>()
134+
..add(InitWorkspaceEvent(tab: selectedTab))
94135
..add(const GetTimelineItemsEvent());
95136
}
96137

138+
WorkspacePageTab _determineTab(WorkspacePageTab? initialTab) {
139+
return initialTab ?? widget.tab ?? WorkspacePageTab.proposals;
140+
}
141+
97142
void _dontShowCampaignSubmissionClosingDialog(bool value) {
98143
context.read<SessionCubit>().updateShowSubmissionClosingWarning(value: !value);
99144
}
@@ -138,4 +183,16 @@ class _WorkspacePageState extends State<WorkspacePage>
138183
dontShowAgain: _dontShowCampaignSubmissionClosingDialog,
139184
);
140185
}
186+
187+
void _updateRoute({
188+
WorkspacePageTab? tab,
189+
}) {
190+
Router.neglect(context, () {
191+
final effectiveTab = tab ?? widget.tab;
192+
193+
WorkspaceRoute(
194+
tab: effectiveTab?.name,
195+
).replace(context);
196+
});
197+
}
141198
}

β€Žcatalyst_voices/apps/voices/lib/pages/workspace/page/workspace_user_proposals.dartβ€Ž

Lines changed: 0 additions & 20 deletions
This file was deleted.

0 commit comments

Comments
Β (0)