Skip to content
This repository has been archived by the owner on Jul 31, 2021. It is now read-only.

Commit

Permalink
add sentry error reporting, fix vertical orientation, make dev anonym…
Browse files Browse the repository at this point in the history
…ous, refactor message sending to separate class (and fix bug), change swiping suggestions order
  • Loading branch information
mkofdwu committed Feb 5, 2021
1 parent 8b3895a commit 1b16a16
Show file tree
Hide file tree
Showing 11 changed files with 197 additions and 149 deletions.
2 changes: 2 additions & 0 deletions integration_test/flows/registration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:tundr/pages/setup/phone_number.dart';
import 'package:tundr/pages/setup/phone_verification.dart';
import 'package:tundr/pages/setup/profile_pic.dart';
import 'package:tundr/pages/setup/theme.dart';
import 'package:tundr/pages/welcome.dart';
import 'package:tundr/widgets/scroll_down_arrow.dart';
import 'package:tundr/widgets/textfields/digit.dart';

Expand All @@ -25,6 +26,7 @@ void main() {
String password,
String confirmPassword,
) async {
expect(find.byType(WelcomePage), findsOneWidget);
await tester.tap(find.byKey(ValueKey('registerBtn')));
await tester.enterText(find.byKey(ValueKey('usernameField')), username);
await tester.enterText(find.byKey(ValueKey('passwordField')), password);
Expand Down
34 changes: 22 additions & 12 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import 'dart:async';

import 'package:feature_discovery/feature_discovery.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:sentry_flutter/sentry_flutter.dart' as sentry;
import 'package:tundr/pages/about.dart';
import 'package:tundr/pages/edit_profile.dart';
import 'package:tundr/pages/me.dart';
Expand Down Expand Up @@ -32,18 +36,22 @@ import 'package:tundr/widgets/handlers/app_state_handler.dart';
import 'package:tundr/widgets/handlers/notification_handler.dart';
import 'package:tundr/widgets/rebuilder.dart';

void main() {
runApp(Rebuilder(
child: MultiProvider(
providers: [
Provider<User>(create: (context) => User()),
Provider<RegistrationInfo>(create: (context) => RegistrationInfo()),
ChangeNotifierProvider<ThemeManager>(
create: (context) => ThemeManager()),
],
child: TundrApp(),
),
));
Future<void> main() async {
await sentry.SentryFlutter.init(
(options) => options.dsn =
'https://[email protected]/5624275',
appRunner: () => runApp(Rebuilder(
child: MultiProvider(
providers: [
Provider<User>(create: (context) => User()),
Provider<RegistrationInfo>(create: (context) => RegistrationInfo()),
ChangeNotifierProvider<ThemeManager>(
create: (context) => ThemeManager()),
],
child: TundrApp(),
),
)),
);
}

class TundrApp extends StatefulWidget {
Expand Down Expand Up @@ -94,6 +102,8 @@ class _TundrAppState extends State<TundrApp> {

@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
return Consumer<User>(
builder: (context, user, child) {
Widget home;
Expand Down
4 changes: 2 additions & 2 deletions lib/pages/about.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ class AboutPage extends StatelessWidget {
),
SizedBox(height: 10),
Text(
'Developed by Jia Jie',
'Developed by someone single', // Jia Jie
style: TextStyle(
fontSize: 14,
),
),
Text(
'Version: 0.1.0a',
'Version: 0.2.1',
style: TextStyle(
fontSize: 14,
),
Expand Down
158 changes: 42 additions & 116 deletions lib/pages/chat/chat.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ import 'package:tundr/enums/chat_type.dart';
import 'package:tundr/models/chat.dart';
import 'package:tundr/models/media.dart';
import 'package:tundr/models/message.dart';
import 'package:tundr/models/user_status.dart';
import 'package:tundr/pages/chat/message_sender.dart';
import 'package:tundr/pages/chat/widgets/chat_description.dart';
import 'package:tundr/pages/chat/widgets/message_field.dart';
import 'package:tundr/pages/chat/widgets/popup_menu.dart';

import 'package:tundr/store/user.dart';
import 'package:tundr/services/chats_service.dart';
import 'package:tundr/services/storage_service.dart';
import 'package:tundr/services/users_service.dart';
import 'package:tundr/utils/format_date.dart';
import 'package:tundr/utils/from_theme.dart';
import 'package:tundr/utils/get_network_image.dart';
import 'package:tundr/utils/show_info_dialog.dart';
Expand All @@ -41,23 +40,23 @@ class _ChatPageState extends State<ChatPage> {
int _pages = 1;

final ScrollController _scrollController = ScrollController();
Media _media;
Media _messageMedia;
Message _referencedMessage;
bool _showChatOptions = false;
final List<Message> _unsentMessages = [];
// final List<Message> _unsentMessages = [];
MessageSender messageSender;

final Map<String, GlobalKey> messageIdToGlobalKey = {};

@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((duration) async {
final user = Provider.of<User>(context, listen: false);
messageSender = MessageSender(uid: user.profile.uid, chat: widget.chat);
if (widget.chat.type != ChatType.nonExistent &&
widget.chat.type != ChatType.newMatch) {
if (Provider.of<User>(context, listen: false)
.privateInfo
.settings
.readReceipts) {
if (user.privateInfo.settings.readReceipts) {
// only send read receipts if the user's settings allows
await ChatsService.readOtherUsersMessages(
widget.chat.otherProfile.uid,
Expand Down Expand Up @@ -98,84 +97,6 @@ class _ChatPageState extends State<ChatPage> {
}
}

void _deleteMessage(String messageId) {
ChatsService.deleteMessage(
chatId: widget.chat.id,
messageId: messageId,
);
}

void _sendMessage(String text) async {
final profile = Provider.of<User>(context, listen: false).profile;
final unsentMessageIndex = _unsentMessages.length;
final sentOn = DateTime.now();

final message = Message(
sender: profile,
sentOn: sentOn,
readOn: null,
referencedMessage: _referencedMessage,
text: text,
media: _media,
);

setState(() {
_media = null;
_referencedMessage = null;
_unsentMessages.add(message);
widget.chat.lastReadMessageId = null;
});

if (message.media != null) {
message.media.url = await StorageService.uploadMedia(
uid: profile.uid, media: message.media);
message.media.isLocalFile = false;
}

if (widget.chat.type == ChatType.nonExistent) {
widget.chat.id = await ChatsService.startConversation(
widget.chat.otherProfile.uid,
message,
);
} else if (widget.chat.type == ChatType.newMatch) {
await ChatsService.updateChatDetails(
profile.uid,
widget.chat.id,
{'type': 3},
); // normal
} else if (widget.chat.type == ChatType.unknown) {
await ChatsService.updateChatDetails(
profile.uid,
widget.chat.id,
{'type': 3},
);
}

if (widget.chat.type != ChatType.nonExistent) {
// when calling the startConversation http function a message is already created
await ChatsService.sendMessage(widget.chat.id, message);
}

if (mounted) {
setState(() {
widget.chat.type = ChatType.normal;
_unsentMessages.removeAt(unsentMessageIndex);
});
}
}

Widget _buildUserStatusText() => StreamBuilder<UserStatus>(
stream: UsersService.getUserStatusStream(widget.chat.otherProfile.uid),
builder: (context, snapshot) {
if (!snapshot.hasData) return SizedBox.shrink();
final status = snapshot.data;
return Text(
status.online ? 'online' : formatDate(status.lastSeen),
style: TextStyle(fontSize: 12, color: MyPalette.white),
);
},
);

Widget _buildTopBar() => SizedBox(
height: 50,
child: Row(
Expand All @@ -196,22 +117,8 @@ class _ChatPageState extends State<ChatPage> {
widget.chat.otherProfile.name,
style: TextStyle(fontSize: 20, color: MyPalette.white),
),
StreamBuilder<bool>(
stream: ChatsService.otherUserIsTypingStream(widget.chat),
builder: (context, snapshot) {
if (!snapshot.hasData) return SizedBox.shrink();
if (snapshot.data) {
return Text(
'typing',
style: TextStyle(
fontSize: 12,
color: MyPalette.white,
),
);
}
return _buildUserStatusText();
},
),
if (widget.chat.type != ChatType.nonExistent)
ChatDescription(chat: widget.chat)
],
),
onTap: () async => Navigator.pushNamed(
Expand All @@ -231,13 +138,13 @@ class _ChatPageState extends State<ChatPage> {
);

Widget _buildMessagesList() => StreamBuilder<List<Message>>(
stream: widget.chat.type == ChatType.nonExistent ||
widget.chat.type == ChatType.newMatch
stream: widget.chat.type == ChatType.nonExistent
? null
: ChatsService.messagesStream(
widget.chat.id, _pages * messagesPerPage),
builder: (context, snapshot) {
final messages = snapshot.data ?? [];
final unsentMessages = messageSender?.unsentMessages ?? [];
return NotificationListener(
onNotification: (ScrollNotification notification) {
if (notification is ScrollStartNotification &&
Expand All @@ -252,17 +159,17 @@ class _ChatPageState extends State<ChatPage> {
padding: EdgeInsets.only(
top: 100,
bottom: 120.0 +
(_media == null ? 0 : 220) +
(_messageMedia == null ? 0 : 220) +
(_referencedMessage == null ? 0 : 160),
),
itemCount: _unsentMessages.length + messages.length,
itemCount: unsentMessages.length + messages.length,
itemBuilder: (context, i) {
if (i < _unsentMessages.length) {
if (i < unsentMessages.length) {
return UnsentMessageTile(
message: _unsentMessages[_unsentMessages.length - i - 1],
message: unsentMessages[unsentMessages.length - i - 1],
);
}
final messageIndex = i - _unsentMessages.length;
final messageIndex = i - unsentMessages.length;
final message = messages[messageIndex];
final fromMe = message.sender.uid ==
Provider.of<User>(context, listen: false).profile.uid;
Expand Down Expand Up @@ -304,7 +211,10 @@ class _ChatPageState extends State<ChatPage> {
context, <String>['dismissible_reply']);
},
onDeleteMessage: () {
_deleteMessage(message.id);
ChatsService.deleteMessage(
chatId: widget.chat.id,
messageId: message.id,
);
},
),
),
Expand Down Expand Up @@ -365,7 +275,7 @@ class _ChatPageState extends State<ChatPage> {
Positioned(
bottom: 0,
child: Container(
height: _media == null ? 140 : 300,
height: _messageMedia == null ? 140 : 300,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
gradient: fromTheme(
Expand Down Expand Up @@ -403,18 +313,34 @@ class _ChatPageState extends State<ChatPage> {
);
}
return MessageField(
media: _media,
media: _messageMedia,
referencedMessage: _referencedMessage,
onRemoveMedia: () {
setState(() => _media = null);
setState(() => _messageMedia = null);
},
onRemoveReferencedMessage: () {
setState(() => _referencedMessage = null);
},
onChangeMedia: (newMedia) {
setState(() => _media = newMedia);
setState(() => _messageMedia = newMedia);
},
onSendMessage: (text) async {
final message = Message(
sender: Provider.of<User>(context, listen: false)
.profile,
sentOn: DateTime.now(),
readOn: null,
referencedMessage: _referencedMessage,
text: text,
media: _messageMedia,
);
setState(() {
_messageMedia = null;
_referencedMessage = null;
widget.chat.lastReadMessageId = null;
});
await messageSender.send(message);
},
onSendMessage: _sendMessage,
onStartTyping: () => ChatsService.toggleTyping(
widget.chat.id,
Provider.of<User>(context, listen: false).profile.uid,
Expand Down
Loading

0 comments on commit 1b16a16

Please sign in to comment.