Skip to content

Commit a34d0dc

Browse files
authored
chore: restructure the Flutter app code (#298)
* Collect all custom reusable widgets in the `widgets` module * Group user features in `user` module * Split settings into `user` and `developer` modules * Rename conversation list pane to conversation list * Move core client and extension to `core` module * Split conversation pane into `converation_details` and `message_list` * Move styles into `theme` module * Screens now wrap screen views with required providers * Bundle utilities in `util` module
1 parent 8839dce commit a34d0dc

Some content is hidden

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

59 files changed

+356
-256
lines changed

app/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,23 @@ SPDX-License-Identifier: AGPL-3.0-or-later
88

99
A GUI client for OpenMLS
1010

11+
## Code organization
12+
13+
The app code is organized in the following way:
14+
15+
- Each feature is a separate module in the `lib` directory.
16+
- Each module in the `lib` exports all its public APIs in the dart file with the
17+
same name as the module. Other modules should import this dart file.
18+
- Reusable widgets are in the `widgets` module.
19+
- All styles and theme related code in the `theme` module.
20+
- The module `core` contains the Rust generated code and extensions.
21+
22+
### Naming conventions
23+
24+
- `View` is a pure widget without any providers.
25+
- `Container` wraps a `View` and creates all required providers.
26+
- `ScreenView` is a root widget in the navigation without any providers.
27+
- `Screen` wraps a `ScreenView` and creates all required providers. This is the
28+
actual class used in the navigation stack.
29+
- `Pane` is a widget that is used in large screen layout and divide the screen into
30+
smaller sections.

app/lib/app.dart

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@ import 'package:flutter/material.dart';
88
import 'package:flutter_bloc/flutter_bloc.dart';
99
import 'package:logging/logging.dart';
1010
import 'package:permission_handler/permission_handler.dart';
11-
import 'package:prototype/core_client.dart';
11+
import 'package:prototype/core/core.dart';
1212
import 'package:prototype/navigation/navigation.dart';
13-
import 'package:prototype/platform.dart';
14-
import 'package:prototype/loadable_user_cubit.dart';
15-
import 'package:prototype/user_cubit.dart';
13+
import 'package:prototype/util/platform.dart';
14+
import 'package:prototype/user/user.dart';
1615
import 'package:provider/provider.dart';
1716

1817
import 'registration/registration.dart';

app/lib/conversation_pane/conversation_details/add_members.dart renamed to app/lib/conversation_details/add_members_screen.dart

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44

55
import 'package:flutter/material.dart';
66
import 'package:flutter_bloc/flutter_bloc.dart';
7-
import 'package:prototype/elements.dart';
87
import 'package:prototype/navigation/navigation.dart';
9-
import 'package:prototype/styles.dart';
10-
import 'package:prototype/user_cubit.dart';
8+
import 'package:prototype/theme/theme.dart';
9+
import 'package:prototype/user/user.dart';
10+
import 'package:prototype/widgets/widgets.dart';
1111

1212
import 'add_members_cubit.dart';
1313

14-
class AddMembers extends StatelessWidget {
15-
const AddMembers({super.key});
14+
class AddMembersScreen extends StatelessWidget {
15+
const AddMembersScreen({super.key});
1616

1717
@override
1818
Widget build(BuildContext context) {
@@ -21,13 +21,13 @@ class AddMembers extends StatelessWidget {
2121
final userCubit = context.read<UserCubit>();
2222
return AddMembersCubit()..loadContacts(userCubit.contacts);
2323
},
24-
child: const AddMembersView(),
24+
child: const AddMembersScreenView(),
2525
);
2626
}
2727
}
2828

29-
class AddMembersView extends StatelessWidget {
30-
const AddMembersView({super.key});
29+
class AddMembersScreenView extends StatelessWidget {
30+
const AddMembersScreenView({super.key});
3131

3232
@override
3333
Widget build(BuildContext context) {
@@ -43,7 +43,7 @@ class AddMembersView extends StatelessWidget {
4343
backgroundColor: Colors.white,
4444
elevation: 0,
4545
scrolledUnderElevation: 0,
46-
leading: appBarBackButton(context),
46+
leading: const AppBarBackButton(),
4747
title: const Text("Add members"),
4848
),
4949
body: Padding(

app/lib/conversation_pane/conversation_details/connection_details.dart renamed to app/lib/conversation_details/connection_details.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@
33
// SPDX-License-Identifier: AGPL-3.0-or-later
44

55
import 'package:flutter/material.dart';
6-
import 'package:prototype/core_extension.dart';
7-
import 'package:prototype/elements.dart';
8-
import 'package:prototype/styles.dart';
6+
import 'package:prototype/core/core.dart';
97
import 'package:prototype/theme/theme.dart';
8+
import 'package:prototype/widgets/widgets.dart';
109
import 'package:provider/provider.dart';
1110

1211
import 'conversation_details_cubit.dart';
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// SPDX-FileCopyrightText: 2025 Phoenix R&D GmbH <[email protected]>
2+
//
3+
// SPDX-License-Identifier: AGPL-3.0-or-later
4+
5+
/// The application user features
6+
library;
7+
8+
export 'add_members_screen.dart';
9+
export 'conversation_details_cubit.dart';
10+
export 'conversation_details_screen.dart';
11+
export 'conversation_screen.dart';
12+
export 'member_details_screen.dart';

app/lib/conversation_pane/conversation_details/conversation_details_cubit.dart renamed to app/lib/conversation_details/conversation_details_cubit.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import 'dart:typed_data';
77

88
import 'package:flutter_bloc/flutter_bloc.dart';
99
import 'package:prototype/core/core.dart';
10-
import 'package:prototype/user_cubit.dart';
10+
import 'package:prototype/user/user.dart';
1111

1212
class ConversationDetailsCubit
1313
extends StateStreamableSource<ConversationDetailsState> {

app/lib/conversation_pane/conversation_details/conversation_details.dart renamed to app/lib/conversation_details/conversation_details_screen.dart

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@
55
import 'package:flutter/material.dart';
66
import 'package:flutter_bloc/flutter_bloc.dart';
77
import 'package:prototype/core/core.dart';
8-
import 'package:prototype/elements.dart';
98
import 'package:prototype/navigation/navigation.dart';
9+
import 'package:prototype/widgets/widgets.dart';
1010

1111
import 'connection_details.dart';
1212
import 'conversation_details_cubit.dart';
1313
import 'group_details.dart';
1414

15-
/// Container for [ConversationDetailsScreen]
15+
/// Container for [ConversationDetailsScreenView]
1616
///
1717
/// Wraps the screen with required providers.
18-
class ConversationDetailsContainer extends StatelessWidget {
19-
const ConversationDetailsContainer({super.key});
18+
class ConversationDetailsScreen extends StatelessWidget {
19+
const ConversationDetailsScreen({super.key});
2020

2121
@override
2222
Widget build(BuildContext context) {
@@ -32,14 +32,14 @@ class ConversationDetailsContainer extends StatelessWidget {
3232
userCubit: context.read(),
3333
conversationId: conversationId,
3434
),
35-
child: ConversationDetailsScreen(),
35+
child: ConversationDetailsScreenView(),
3636
);
3737
}
3838
}
3939

4040
/// Screen that shows details of a conversation
41-
class ConversationDetailsScreen extends StatelessWidget {
42-
const ConversationDetailsScreen({super.key});
41+
class ConversationDetailsScreenView extends StatelessWidget {
42+
const ConversationDetailsScreenView({super.key});
4343

4444
@override
4545
Widget build(BuildContext context) {
@@ -51,7 +51,7 @@ class ConversationDetailsScreen extends StatelessWidget {
5151
backgroundColor: Colors.white,
5252
elevation: 0,
5353
scrolledUnderElevation: 0,
54-
leading: appBarBackButton(context),
54+
leading: const AppBarBackButton(),
5555
title: const Text("Details"),
5656
),
5757
body: switch (conversationType) {

app/lib/conversation_pane/conversation_pane.dart renamed to app/lib/conversation_details/conversation_screen.dart

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,16 @@
44

55
import 'package:flutter/material.dart';
66
import 'package:flutter_bloc/flutter_bloc.dart';
7-
import 'package:prototype/core_extension.dart';
8-
import 'package:prototype/elements.dart';
7+
import 'package:prototype/core/core.dart';
8+
import 'package:prototype/message_list/message_list.dart';
99
import 'package:prototype/navigation/navigation.dart';
10-
import 'package:prototype/styles.dart';
1110
import 'package:prototype/theme/theme.dart';
12-
import 'conversation_content/message_list_view.dart';
13-
import 'conversation_details/conversation_details_cubit.dart';
14-
import 'message_composer.dart';
11+
import 'package:prototype/widgets/widgets.dart';
1512

16-
class ConversationPaneContainer extends StatelessWidget {
17-
const ConversationPaneContainer({super.key});
13+
import 'conversation_details_cubit.dart';
14+
15+
class ConversationScreen extends StatelessWidget {
16+
const ConversationScreen({super.key});
1817

1918
@override
2019
Widget build(BuildContext context) {
@@ -32,7 +31,7 @@ class ConversationPaneContainer extends StatelessWidget {
3231
userCubit: context.read(),
3332
conversationId: conversationId,
3433
),
35-
child: const ConversationPane(),
34+
child: const ConversationScreenView(),
3635
);
3736
}
3837
}
@@ -53,8 +52,8 @@ class _EmptyConversationPane extends StatelessWidget {
5352
}
5453
}
5554

56-
class ConversationPane extends StatelessWidget {
57-
const ConversationPane({super.key});
55+
class ConversationScreenView extends StatelessWidget {
56+
const ConversationScreenView({super.key});
5857

5958
@override
6059
Widget build(BuildContext context) {
@@ -89,8 +88,9 @@ class ConversationPane extends StatelessWidget {
8988
elevation: 0,
9089
// Applying blur effect
9190
flexibleSpace: FrostedGlass(
92-
color: Colors.white,
93-
height: kToolbarHeight + MediaQuery.of(context).padding.top),
91+
color: Colors.white,
92+
height: kToolbarHeight + MediaQuery.of(context).padding.top,
93+
),
9494
),
9595
),
9696
]),

app/lib/conversation_pane/conversation_details/group_details.dart renamed to app/lib/conversation_details/group_details.dart

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@
44

55
import 'package:flutter/material.dart';
66
import 'package:image_picker/image_picker.dart';
7-
import 'package:prototype/core_extension.dart';
8-
import 'package:prototype/elements.dart';
7+
import 'package:prototype/core/core.dart';
98
import 'package:prototype/navigation/navigation.dart';
10-
import 'package:prototype/styles.dart';
119
import 'package:prototype/theme/theme.dart';
12-
import 'package:prototype/user_cubit.dart';
10+
import 'package:prototype/user/user.dart';
11+
import 'package:prototype/widgets/widgets.dart';
1312
import 'package:provider/provider.dart';
1413

1514
import 'conversation_details_cubit.dart';

0 commit comments

Comments
 (0)