mirror of
https://gitlab.com/comunic/comunicmobile
synced 2024-12-28 22:08:50 +00:00
194 lines
5.6 KiB
Dart
194 lines
5.6 KiB
Dart
import 'package:comunic/helpers/conversations_helper.dart';
|
|
import 'package:comunic/helpers/events_helper.dart';
|
|
import 'package:comunic/models/conversation.dart';
|
|
import 'package:comunic/ui/dialogs/screen_dialog.dart';
|
|
import 'package:comunic/ui/routes/main_route/main_route.dart';
|
|
import 'package:comunic/ui/routes/update_conversation_route.dart';
|
|
import 'package:comunic/ui/screens/conversation_members_screen.dart';
|
|
import 'package:comunic/ui/screens/conversation_screen.dart';
|
|
import 'package:comunic/ui/widgets/safe_state.dart';
|
|
import 'package:comunic/ui/widgets/tablet_mode/conversations/conversation_window_container.dart';
|
|
import 'package:comunic/utils/account_utils.dart';
|
|
import 'package:comunic/utils/intl_utils.dart';
|
|
import 'package:comunic/utils/ui_utils.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
/// Single conversation window
|
|
///
|
|
/// @author Pierre Hubert
|
|
|
|
enum _Actions { OPEN_FULL_SCREEN, OPEN_MEMBERS, OPEN_SETTINGS }
|
|
|
|
class ConversationWindow extends StatefulWidget {
|
|
final int convID;
|
|
final Function() onClose;
|
|
|
|
const ConversationWindow({
|
|
Key key,
|
|
@required this.convID,
|
|
@required this.onClose,
|
|
}) : assert(convID != null),
|
|
assert(onClose != null),
|
|
super(key: key);
|
|
|
|
@override
|
|
_ConversationWindowState createState() => _ConversationWindowState();
|
|
}
|
|
|
|
class _ConversationWindowState extends SafeState<ConversationWindow> {
|
|
Conversation _conversation;
|
|
String _convTitle;
|
|
bool _error = false;
|
|
bool _collapsed = false;
|
|
bool _hasNewMessages = false;
|
|
|
|
int get _convID => widget.convID;
|
|
|
|
final _convKey = UniqueKey();
|
|
|
|
void _setError(bool e) => setState(() => _error = e);
|
|
|
|
void _toggleVisibility() => setState(() {
|
|
_collapsed = !_collapsed;
|
|
if (!_collapsed) _hasNewMessages = false;
|
|
});
|
|
|
|
Future<void> _refresh() async {
|
|
try {
|
|
_setError(false);
|
|
|
|
final conversation =
|
|
await ConversationsHelper().getSingle(_convID, force: true);
|
|
assert(conversation != null);
|
|
final name =
|
|
await ConversationsHelper.getConversationNameAsync(conversation);
|
|
assert(name != null);
|
|
|
|
setState(() {
|
|
_conversation = conversation;
|
|
_convTitle = name;
|
|
});
|
|
} catch (e, s) {
|
|
_setError(true);
|
|
print("Could not refresh the list of conversations! $e\n$s");
|
|
showSimpleSnack(context, tr("Could not load conversation information!"));
|
|
}
|
|
}
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_refresh();
|
|
|
|
listen<NewConversationMessageEvent>((e) {
|
|
if (e.msg.convID == _convID && _collapsed && e.msg.userID != userID())
|
|
setState(() => _hasNewMessages = true);
|
|
});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
// In case of error
|
|
if (_error)
|
|
return ConversationWindowContainer(
|
|
icon: Icon(Icons.error),
|
|
title: Text(tr("Error")),
|
|
onClose: widget.onClose,
|
|
onToggleCollapse: _toggleVisibility,
|
|
isCollapsed: _collapsed,
|
|
body: buildErrorCard(tr("Could not load conversation information!"),
|
|
actions: [
|
|
ElevatedButton(
|
|
onPressed: _refresh,
|
|
child: Text(tr("Try again").toUpperCase()),
|
|
)
|
|
]),
|
|
);
|
|
|
|
// If it is still loading
|
|
if (_conversation == null)
|
|
return ConversationWindowContainer(
|
|
icon: Icon(Icons.message),
|
|
title: Text(tr("Loading...")),
|
|
onClose: widget.onClose,
|
|
onToggleCollapse: _toggleVisibility,
|
|
isCollapsed: _collapsed,
|
|
body: buildCenteredProgressBar(),
|
|
);
|
|
|
|
return ConversationWindowContainer(
|
|
icon: _hasNewMessages ? Icon(Icons.trip_origin) : null,
|
|
appBarBgColor: _hasNewMessages ? Colors.green : null,
|
|
title: Text(_convTitle),
|
|
onClose: widget.onClose,
|
|
onToggleCollapse: _toggleVisibility,
|
|
isCollapsed: _collapsed,
|
|
action: (_conversation.callCapabilities != CallCapabilities.NONE
|
|
? [IconButton(icon: Icon(Icons.call), onPressed: _startCall)]
|
|
: [])
|
|
..addAll(<Widget>[
|
|
PopupMenuButton<_Actions>(
|
|
itemBuilder: (c) => [
|
|
// Show in full screen
|
|
PopupMenuItem(
|
|
child: Text(tr("Open in full screen")),
|
|
value: _Actions.OPEN_FULL_SCREEN,
|
|
),
|
|
|
|
// Show the list of members
|
|
PopupMenuItem(
|
|
child: Text(tr("Members")),
|
|
value: _Actions.OPEN_MEMBERS,
|
|
),
|
|
|
|
// Show conversation settings
|
|
PopupMenuItem(
|
|
child: Text(tr("Settings")),
|
|
value: _Actions.OPEN_SETTINGS,
|
|
)
|
|
],
|
|
onSelected: _menuCallback,
|
|
),
|
|
]),
|
|
body: ConversationScreen(
|
|
key: _convKey,
|
|
conversationID: _convID,
|
|
),
|
|
);
|
|
}
|
|
|
|
void _menuCallback(_Actions value) {
|
|
switch (value) {
|
|
case _Actions.OPEN_FULL_SCREEN:
|
|
_openFullScreen();
|
|
break;
|
|
|
|
case _Actions.OPEN_MEMBERS:
|
|
_openMembersList();
|
|
break;
|
|
|
|
case _Actions.OPEN_SETTINGS:
|
|
_openConversationSettings();
|
|
break;
|
|
}
|
|
}
|
|
|
|
void _openFullScreen() {
|
|
MainController.of(context)
|
|
.openConversation(_conversation, fullScreen: true);
|
|
widget.onClose();
|
|
}
|
|
|
|
void _openMembersList() {
|
|
showScreenDialog(context, ConversationMembersScreen(convID: _convID));
|
|
}
|
|
|
|
void _openConversationSettings() async {
|
|
await showScreenDialog(
|
|
context, UpdateConversationRoute(conversationID: _convID));
|
|
_refresh();
|
|
}
|
|
|
|
void _startCall() => MainController.of(context).startCall(_convID);
|
|
}
|