2020-05-10 11:46:45 +00:00
|
|
|
import 'package:comunic/ui/screens/call_screen.dart';
|
2020-05-10 13:00:26 +00:00
|
|
|
import 'package:comunic/ui/widgets/custom_app_bar_size.dart';
|
2020-05-10 12:09:44 +00:00
|
|
|
import 'package:comunic/ui/widgets/tablet_mode/calls/calls_area.dart';
|
2020-05-10 13:00:26 +00:00
|
|
|
import 'package:comunic/utils/intl_utils.dart';
|
2020-05-10 11:46:45 +00:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
|
|
|
/// Call window widget
|
|
|
|
///
|
|
|
|
/// @author Pierre HUBERT
|
|
|
|
|
2020-05-10 13:00:26 +00:00
|
|
|
const _WindowSize = Size(450, 200);
|
2020-05-10 12:09:44 +00:00
|
|
|
|
2020-05-10 11:46:45 +00:00
|
|
|
class CallWindowWidget extends StatefulWidget {
|
|
|
|
final int convID;
|
2020-05-10 13:00:26 +00:00
|
|
|
final void Function() onClose;
|
2020-05-10 11:46:45 +00:00
|
|
|
|
|
|
|
const CallWindowWidget({
|
2022-03-10 18:39:57 +00:00
|
|
|
Key? key,
|
|
|
|
required this.convID,
|
|
|
|
required this.onClose,
|
2020-05-10 11:46:45 +00:00
|
|
|
}) : assert(convID != null),
|
2020-05-10 13:00:26 +00:00
|
|
|
assert(onClose != null),
|
2020-05-10 11:46:45 +00:00
|
|
|
super(key: key);
|
|
|
|
|
|
|
|
@override
|
|
|
|
_CallWindowWidgetState createState() => _CallWindowWidgetState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class _CallWindowWidgetState extends State<CallWindowWidget> {
|
2022-03-10 18:39:57 +00:00
|
|
|
double? _left, _top;
|
2020-05-10 12:09:44 +00:00
|
|
|
|
2020-05-10 13:21:01 +00:00
|
|
|
var _fullScreen = false;
|
|
|
|
|
|
|
|
final _callScreenKey = GlobalKey();
|
|
|
|
|
2020-05-10 12:09:44 +00:00
|
|
|
@override
|
|
|
|
void didChangeDependencies() {
|
|
|
|
super.didChangeDependencies();
|
|
|
|
|
|
|
|
// Initialize window coordinates
|
|
|
|
_top = 10;
|
|
|
|
_left = MediaQuery.of(context).size.width - 10 - _WindowSize.width;
|
|
|
|
}
|
|
|
|
|
2020-05-10 11:46:45 +00:00
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
2020-05-10 13:21:01 +00:00
|
|
|
if (_fullScreen) return _buildScreen();
|
|
|
|
|
2020-05-10 11:46:45 +00:00
|
|
|
return Positioned(
|
2020-05-10 12:09:44 +00:00
|
|
|
width: _WindowSize.width,
|
|
|
|
height: _WindowSize.height,
|
|
|
|
left: _left,
|
|
|
|
top: _top,
|
|
|
|
child: Draggable(
|
2020-05-10 12:32:44 +00:00
|
|
|
child: Card(
|
2020-05-10 13:21:01 +00:00
|
|
|
child: _buildScreen(),
|
2020-05-10 12:32:44 +00:00
|
|
|
),
|
2020-05-10 12:09:44 +00:00
|
|
|
feedback: Container(
|
|
|
|
width: _WindowSize.width,
|
|
|
|
height: _WindowSize.height,
|
|
|
|
color: Colors.red,
|
|
|
|
),
|
|
|
|
onDragEnd: _moveEnd,
|
|
|
|
),
|
2020-05-10 11:46:45 +00:00
|
|
|
);
|
|
|
|
}
|
2020-05-10 12:09:44 +00:00
|
|
|
|
2020-05-10 13:21:01 +00:00
|
|
|
Widget _buildScreen() => CallScreen(
|
|
|
|
key: _callScreenKey,
|
|
|
|
buildCustomAppBar: (convName) => AppBarWrapper(
|
|
|
|
height: 30,
|
|
|
|
appBar: AppBar(
|
|
|
|
backgroundColor: Colors.black,
|
2022-03-10 18:39:57 +00:00
|
|
|
title: Text(convName == null ? tr("Loading...")! : convName),
|
2020-05-10 13:21:01 +00:00
|
|
|
actions: <Widget>[
|
|
|
|
// Go full screen
|
|
|
|
IconButton(
|
|
|
|
iconSize: 16,
|
|
|
|
icon: Icon(
|
|
|
|
_fullScreen ? Icons.fullscreen_exit : Icons.fullscreen),
|
|
|
|
onPressed: _toggleFullScreen,
|
|
|
|
),
|
|
|
|
|
|
|
|
// Close call
|
|
|
|
IconButton(
|
|
|
|
iconSize: 16,
|
|
|
|
icon: Icon(Icons.close),
|
|
|
|
onPressed: widget.onClose,
|
|
|
|
)
|
|
|
|
],
|
|
|
|
)),
|
|
|
|
convID: widget.convID,
|
|
|
|
floatingButtons: _fullScreen,
|
|
|
|
onClose: widget.onClose,
|
|
|
|
);
|
|
|
|
|
2020-05-10 12:09:44 +00:00
|
|
|
/// Compute new window position
|
|
|
|
void _moveEnd(DraggableDetails details) {
|
|
|
|
// Determine the limits of containing stack
|
|
|
|
RenderBox renderBox = context
|
2022-03-10 18:39:57 +00:00
|
|
|
.findAncestorStateOfType<CallsAreaState>()!
|
2020-05-10 12:09:44 +00:00
|
|
|
.context
|
2022-03-10 18:39:57 +00:00
|
|
|
.findRenderObject() as RenderBox;
|
2020-05-10 12:09:44 +00:00
|
|
|
final size = renderBox.size;
|
|
|
|
final offset = renderBox.localToGlobal(Offset.zero);
|
|
|
|
|
|
|
|
// Determine new window position
|
|
|
|
_top = details.offset.dy - offset.dy;
|
|
|
|
_left = details.offset.dx - offset.dx;
|
|
|
|
|
|
|
|
// Force the window to appear completely on the screen
|
2022-03-10 18:39:57 +00:00
|
|
|
if (_top! + _WindowSize.height >= size.height)
|
2020-05-10 12:09:44 +00:00
|
|
|
_top = size.height - _WindowSize.height;
|
2022-03-10 18:39:57 +00:00
|
|
|
if (_left! + _WindowSize.width >= size.width)
|
2020-05-10 12:09:44 +00:00
|
|
|
_left = size.width - _WindowSize.width;
|
|
|
|
|
2022-03-10 18:39:57 +00:00
|
|
|
if (_top! < 0) _top = 0;
|
|
|
|
if (_left! < 0) _left = 0;
|
2020-05-10 12:09:44 +00:00
|
|
|
|
|
|
|
setState(() {});
|
|
|
|
}
|
2020-05-10 13:21:01 +00:00
|
|
|
|
|
|
|
void _toggleFullScreen() => setState(() => _fullScreen = !_fullScreen);
|
2020-05-10 11:46:45 +00:00
|
|
|
}
|