Skip to content

Commit

Permalink
refactor: Use flutter redux for state management.
Browse files Browse the repository at this point in the history
  • Loading branch information
iphydf committed Nov 2, 2024
1 parent d798045 commit bf0d5e6
Show file tree
Hide file tree
Showing 20 changed files with 232 additions and 145 deletions.
4 changes: 2 additions & 2 deletions lib/add_contact_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:flutter/material.dart';

import 'strings.dart';

class AddContactPage extends StatefulWidget {
final class AddContactPage extends StatefulWidget {
const AddContactPage({super.key, required this.onAddContact});

final Function(String, String) onAddContact;
Expand All @@ -11,7 +11,7 @@ class AddContactPage extends StatefulWidget {
State<AddContactPage> createState() => _AddContactPageState();
}

class _AddContactPageState extends State<AddContactPage> {
final class _AddContactPageState extends State<AddContactPage> {
final _formKey = GlobalKey<FormState>();
final _toxIdInputController = TextEditingController();
final _messageInputController =
Expand Down
22 changes: 0 additions & 22 deletions lib/app.dart

This file was deleted.

7 changes: 0 additions & 7 deletions lib/app_state.dart

This file was deleted.

11 changes: 11 additions & 0 deletions lib/btox_actions.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class BtoxUpdateNicknameAction {
final String nickname;

const BtoxUpdateNicknameAction(this.nickname);
}

class BtoxUpdateStatusMessageAction {
final String statusMessage;

const BtoxUpdateStatusMessageAction(this.statusMessage);
}
32 changes: 32 additions & 0 deletions lib/btox_app.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import 'package:btox/btox_state.dart';
import 'package:btox/contact_list_page.dart';
import 'package:btox/db/database.dart';
import 'package:btox/strings.dart';
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:redux/redux.dart';

final class BtoxApp extends StatelessWidget {
final Database database;
final Store<BtoxState> store;

const BtoxApp({
super.key,
required this.database,
required this.store,
});

@override
Widget build(BuildContext context) {
return StoreProvider<BtoxState>(
store: store,
child: MaterialApp(
title: Strings.title,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ContactListPage(title: Strings.title, database: database),
),
);
}
}
18 changes: 18 additions & 0 deletions lib/btox_reducer.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import 'package:btox/btox_state.dart';
import 'package:btox/btox_actions.dart';
import 'package:redux/redux.dart';

final btoxReducer = combineReducers<BtoxState>([
TypedReducer<BtoxState, BtoxUpdateNicknameAction>(_updateNickname).call,
TypedReducer<BtoxState, BtoxUpdateStatusMessageAction>(_updateStatusMessage)
.call,
]);

BtoxState _updateNickname(BtoxState state, BtoxUpdateNicknameAction action) {
return state.copyWith(nickname: action.nickname);
}

BtoxState _updateStatusMessage(
BtoxState state, BtoxUpdateStatusMessageAction action) {
return state.copyWith(statusMessage: action.statusMessage);
}
23 changes: 23 additions & 0 deletions lib/btox_state.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
final class BtoxState {
final String nickname;
final String statusMessage;

const BtoxState({
required this.nickname,
required this.statusMessage,
});

const BtoxState.initial()
: nickname = 'Yanciman',
statusMessage = 'Producing works of art in Kannywood';

BtoxState copyWith({
String? nickname,
String? statusMessage,
}) {
return BtoxState(
nickname: nickname ?? this.nickname,
statusMessage: statusMessage ?? this.statusMessage,
);
}
}
27 changes: 13 additions & 14 deletions lib/chat_page.dart
Original file line number Diff line number Diff line change
@@ -1,34 +1,27 @@
import 'package:btox/db/database.dart';
import 'package:btox/strings.dart';
import 'package:flutter/material.dart';

import 'db/database.dart';
import 'strings.dart';
final class ChatPage extends StatefulWidget {
final Stream<Contact> contact;
final Stream<List<Message>> messages;
final void Function(String message) onSendMessage;

class ChatPage extends StatefulWidget {
const ChatPage({
super.key,
required this.contact,
required this.messages,
required this.onSendMessage,
});

final Stream<Contact> contact;
final Stream<List<Message>> messages;
final void Function(String message) onSendMessage;

@override
State<ChatPage> createState() => _ChatPageState();
}

class _ChatPageState extends State<ChatPage> {
final class _ChatPageState extends State<ChatPage> {
final _messageInputFocus = FocusNode();
final _messageInputController = TextEditingController();

void _onSendMessage() {
widget.onSendMessage(_messageInputController.text);
_messageInputController.clear();
_messageInputFocus.requestFocus();
}

@override
Widget build(BuildContext context) {
return StreamBuilder<Contact>(
Expand Down Expand Up @@ -82,4 +75,10 @@ class _ChatPageState extends State<ChatPage> {
),
);
}

void _onSendMessage() {
widget.onSendMessage(_messageInputController.text);
_messageInputController.clear();
_messageInputFocus.requestFocus();
}
}
88 changes: 47 additions & 41 deletions lib/contact_list_page.dart
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
import 'package:btox/add_contact_page.dart';
import 'package:btox/btox_state.dart';
import 'package:btox/chat_page.dart';
import 'package:btox/db/database.dart';
import 'package:btox/profile.dart';
import 'package:btox/settings.dart';
import 'package:btox/strings.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_redux/flutter_redux.dart';

import 'add_contact_page.dart';
import 'app_state.dart';
import 'chat_page.dart';
import 'db/database.dart';
import 'profile.dart';
import 'settings.dart';
import 'strings.dart';

class ContactListItem extends StatelessWidget {
const ContactListItem(
{super.key, required this.contact, required this.onTap});

final class ContactListItem extends StatelessWidget {
final Contact contact;
final Function(Contact) onTap;

const ContactListItem({
super.key,
required this.contact,
required this.onTap,
});

@override
Widget build(BuildContext context) {
return ListTile(
Expand All @@ -27,25 +30,15 @@ class ContactListItem extends StatelessWidget {
}
}

class ContactListPage extends StatefulWidget {
ContactListPage({super.key, required this.title, required this.database});

final class ContactListPage extends StatelessWidget {
final String title;
final Database database;
final appState = AppState();

@override
State<ContactListPage> createState() => _ContactListPageState();
}

class _ContactListPageState extends State<ContactListPage> {
void _onAddContact(String toxID, String message) {
widget.database.addContact(
ContactsCompanion.insert(
publicKey: toxID.substring(0, toxID.length - 12),
),
);
}
const ContactListPage({
super.key,
required this.title,
required this.database,
});

@override
Widget build(BuildContext context) {
Expand All @@ -59,9 +52,9 @@ class _ContactListPageState extends State<ContactListPage> {
color: Colors.blue,
),
child: ListTile(
title: ValueListenableBuilder(
valueListenable: widget.appState.nickname,
builder: (context, String nickname, _) {
title: StoreConnector<BtoxState, String>(
converter: (store) => store.state.nickname,
builder: (context, nickname) {
return Text(
nickname,
style: const TextStyle(
Expand All @@ -72,9 +65,9 @@ class _ContactListPageState extends State<ContactListPage> {
);
},
),
subtitle: ValueListenableBuilder(
valueListenable: widget.appState.statusMessage,
builder: (context, String statusMessage, _) {
subtitle: StoreConnector<BtoxState, String>(
converter: (store) => store.state.statusMessage,
builder: (context, String statusMessage) {
return Text(
statusMessage,
style: const TextStyle(
Expand All @@ -95,8 +88,13 @@ class _ContactListPageState extends State<ContactListPage> {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
UserProfilePage(appState: widget.appState),
builder: (context) => StoreConnector<BtoxState, BtoxState>(
converter: (store) => store.state,
builder: (context, state) => UserProfilePage(
state: state,
store: StoreProvider.of(context),
),
),
),
);
},
Expand Down Expand Up @@ -137,10 +135,10 @@ class _ContactListPageState extends State<ContactListPage> {
);
},
),
title: Text(widget.title),
title: Text(title),
),
body: StreamBuilder<List<Contact>>(
stream: widget.database.watchContacts(),
stream: database.watchContacts(),
builder: ((context, snapshot) {
final contacts = snapshot.data ?? [];

Expand All @@ -154,10 +152,10 @@ class _ContactListPageState extends State<ContactListPage> {
context,
MaterialPageRoute(
builder: (context) => ChatPage(
contact: widget.database.watchContact(contact.id),
messages: widget.database.watchMessagesFor(contact.id),
contact: database.watchContact(contact.id),
messages: database.watchMessagesFor(contact.id),
onSendMessage: (String message) {
widget.database.addMessage(MessagesCompanion.insert(
database.addMessage(MessagesCompanion.insert(
contactId: contact.id,
content: message,
timestamp: DateTime.now().toUtc(),
Expand All @@ -184,4 +182,12 @@ class _ContactListPageState extends State<ContactListPage> {
),
);
}

void _onAddContact(String toxID, String message) {
database.addContact(
ContactsCompanion.insert(
publicKey: toxID.substring(0, toxID.length - 12),
),
);
}
}
2 changes: 1 addition & 1 deletion lib/db/database.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class Messages extends Table {
}

@DriftDatabase(tables: [Contacts, Messages])
class Database extends _$Database {
final class Database extends _$Database {
Database(super.e);

@override
Expand Down
3 changes: 1 addition & 2 deletions lib/db/native.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import 'dart:io';

import 'package:btox/db/database.dart';
import 'package:drift/drift.dart';
import 'package:drift/native.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';

import 'database.dart';

Database constructDb() {
return Database(
LazyDatabase(() async {
Expand Down
2 changes: 1 addition & 1 deletion lib/db/unsupported.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import 'database.dart';
import 'package:btox/db/database.dart';

Database constructDb() => throw UnimplementedError();
3 changes: 1 addition & 2 deletions lib/db/web.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import 'package:btox/db/database.dart';
import 'package:drift/drift.dart';
import 'package:drift/wasm.dart';

import 'database.dart';

Database constructDb() => Database(
DatabaseConnection.delayed(Future(() async => (await WasmDatabase.open(
databaseName: 'db',
Expand Down
Loading

0 comments on commit bf0d5e6

Please sign in to comment.