2023-08-05 19:34:00 -04:00
|
|
|
import 'dart:async';
|
|
|
|
|
2023-01-08 22:27:33 -05:00
|
|
|
import 'package:flutter/material.dart';
|
2023-07-26 22:38:09 -04:00
|
|
|
import 'package:flutter_animate/flutter_animate.dart';
|
2023-01-09 22:50:34 -05:00
|
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
2023-07-29 10:55:35 -04:00
|
|
|
import 'package:split_view/split_view.dart';
|
2023-07-26 22:38:09 -04:00
|
|
|
import 'package:signal_strength_indicator/signal_strength_indicator.dart';
|
2023-01-08 22:27:33 -05:00
|
|
|
|
2023-07-29 10:55:35 -04:00
|
|
|
import '../components/chat_component.dart';
|
2023-08-05 19:34:00 -04:00
|
|
|
import '../providers/account.dart';
|
|
|
|
import '../providers/contact.dart';
|
2023-08-02 21:09:28 -04:00
|
|
|
import '../providers/local_accounts.dart';
|
|
|
|
import '../providers/logins.dart';
|
2023-07-28 20:36:05 -04:00
|
|
|
import '../providers/window_control.dart';
|
2023-07-26 22:38:09 -04:00
|
|
|
import '../tools/tools.dart';
|
2023-08-05 19:34:00 -04:00
|
|
|
import '../veilid_support/dht_support/dht_record_pool.dart';
|
2023-07-28 20:36:05 -04:00
|
|
|
import 'main_pager/main_pager.dart';
|
2023-07-26 22:38:09 -04:00
|
|
|
|
|
|
|
class HomePage extends ConsumerStatefulWidget {
|
2023-01-09 22:50:34 -05:00
|
|
|
const HomePage({super.key});
|
|
|
|
static const path = '/home';
|
2023-01-08 22:27:33 -05:00
|
|
|
|
|
|
|
@override
|
2023-07-26 22:38:09 -04:00
|
|
|
HomePageState createState() => HomePageState();
|
|
|
|
}
|
|
|
|
|
2023-08-05 19:34:00 -04:00
|
|
|
// XXX Eliminate this when we have ValueChanged
|
|
|
|
const int ticksPerContactInvitationCheck = 5;
|
|
|
|
|
2023-07-26 22:38:09 -04:00
|
|
|
class HomePageState extends ConsumerState<HomePage>
|
|
|
|
with TickerProviderStateMixin {
|
|
|
|
final _unfocusNode = FocusNode();
|
2023-07-28 20:36:05 -04:00
|
|
|
|
2023-08-05 19:34:00 -04:00
|
|
|
Timer? _homeTickTimer;
|
|
|
|
bool _inHomeTick = false;
|
|
|
|
int _contactInvitationCheckTick = 0;
|
|
|
|
|
2023-07-26 22:38:09 -04:00
|
|
|
@override
|
|
|
|
void initState() {
|
|
|
|
super.initState();
|
|
|
|
|
2023-07-28 20:36:05 -04:00
|
|
|
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
|
|
|
setState(() {});
|
|
|
|
await ref.read(windowControlProvider.notifier).changeWindowSetup(
|
|
|
|
TitleBarStyle.normal, OrientationCapability.normal);
|
2023-08-05 19:34:00 -04:00
|
|
|
|
|
|
|
_homeTickTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
|
|
|
if (!_inHomeTick) {
|
|
|
|
unawaited(_onHomeTick());
|
|
|
|
}
|
|
|
|
});
|
2023-07-28 20:36:05 -04:00
|
|
|
});
|
2023-07-26 22:38:09 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void dispose() {
|
2023-08-05 19:34:00 -04:00
|
|
|
final homeTickTimer = _homeTickTimer;
|
|
|
|
if (homeTickTimer != null) {
|
|
|
|
homeTickTimer.cancel();
|
|
|
|
}
|
2023-07-26 22:38:09 -04:00
|
|
|
_unfocusNode.dispose();
|
|
|
|
super.dispose();
|
|
|
|
}
|
|
|
|
|
2023-08-05 19:34:00 -04:00
|
|
|
Future<void> _onHomeTick() async {
|
|
|
|
_inHomeTick = true;
|
|
|
|
try {
|
|
|
|
// Check extant contact invitations once every 5 seconds
|
|
|
|
_contactInvitationCheckTick += 1;
|
|
|
|
if (_contactInvitationCheckTick >= ticksPerContactInvitationCheck) {
|
|
|
|
_contactInvitationCheckTick = 0;
|
|
|
|
await _doContactInvitationCheck();
|
|
|
|
}
|
|
|
|
} finally {
|
|
|
|
_inHomeTick = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> _doContactInvitationCheck() async {
|
|
|
|
final contactInvitationRecords =
|
|
|
|
await ref.read(fetchContactInvitationRecordsProvider.future);
|
|
|
|
final activeAccountInfo = await ref.read(fetchActiveAccountProvider.future);
|
|
|
|
if (contactInvitationRecords == null || activeAccountInfo == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
final allChecks = <Future<void>>[];
|
|
|
|
for (final contactInvitationRecord in contactInvitationRecords) {
|
|
|
|
allChecks.add(() async {
|
|
|
|
final acceptReject = await checkAcceptRejectContact(
|
|
|
|
activeAccountInfo: activeAccountInfo,
|
|
|
|
contactInvitationRecord: contactInvitationRecord);
|
|
|
|
if (acceptReject != null) {
|
|
|
|
if (acceptReject) {
|
|
|
|
// Accept
|
|
|
|
ref
|
|
|
|
..invalidate(fetchContactInvitationRecordsProvider)
|
|
|
|
..invalidate(fetchContactListProvider);
|
|
|
|
} else {
|
|
|
|
// Reject
|
|
|
|
ref.invalidate(fetchContactInvitationRecordsProvider);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}());
|
|
|
|
}
|
|
|
|
await Future.wait(allChecks);
|
|
|
|
}
|
|
|
|
|
2023-07-28 20:36:05 -04:00
|
|
|
// ignore: prefer_expression_function_bodies
|
|
|
|
Widget buildPhone(BuildContext context) {
|
|
|
|
//
|
|
|
|
return Material(
|
|
|
|
color: Colors.transparent, elevation: 4, child: MainPager());
|
|
|
|
}
|
|
|
|
|
|
|
|
// ignore: prefer_expression_function_bodies
|
|
|
|
Widget buildTabletLeftPane(BuildContext context) {
|
|
|
|
//
|
|
|
|
return Material(
|
|
|
|
color: Colors.transparent, elevation: 4, child: MainPager());
|
|
|
|
}
|
|
|
|
|
|
|
|
// ignore: prefer_expression_function_bodies
|
|
|
|
Widget buildTabletRightPane(BuildContext context) {
|
|
|
|
//
|
2023-07-29 10:55:35 -04:00
|
|
|
return ChatComponent();
|
2023-07-28 20:36:05 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// ignore: prefer_expression_function_bodies
|
|
|
|
Widget buildTablet(BuildContext context) {
|
2023-07-29 10:55:35 -04:00
|
|
|
final theme = Theme.of(context);
|
|
|
|
final w = MediaQuery.of(context).size.width;
|
2023-07-28 20:36:05 -04:00
|
|
|
final children = [
|
2023-07-29 10:55:35 -04:00
|
|
|
ConstrainedBox(
|
|
|
|
constraints: BoxConstraints(minWidth: 300, maxWidth: 300),
|
|
|
|
child: ConstrainedBox(
|
|
|
|
constraints: BoxConstraints(maxWidth: w / 2),
|
|
|
|
child: buildTabletLeftPane(context))),
|
|
|
|
Expanded(child: buildTabletRightPane(context)),
|
2023-07-28 20:36:05 -04:00
|
|
|
];
|
|
|
|
|
2023-07-29 10:55:35 -04:00
|
|
|
return Row(
|
|
|
|
children: children,
|
|
|
|
);
|
2023-07-28 20:36:05 -04:00
|
|
|
|
2023-07-29 10:55:35 -04:00
|
|
|
// final theme = MultiSplitViewTheme(
|
|
|
|
// data: isDesktop
|
|
|
|
// ? MultiSplitViewThemeData(
|
|
|
|
// dividerThickness: 1,
|
|
|
|
// dividerPainter: DividerPainters.grooved2(thickness: 1))
|
|
|
|
// : MultiSplitViewThemeData(
|
|
|
|
// dividerThickness: 3,
|
|
|
|
// dividerPainter: DividerPainters.grooved2(thickness: 1)),
|
|
|
|
// child: multiSplitView);
|
2023-07-28 20:36:05 -04:00
|
|
|
}
|
|
|
|
|
2023-07-26 22:38:09 -04:00
|
|
|
@override
|
2023-07-28 20:36:05 -04:00
|
|
|
Widget build(BuildContext context) {
|
|
|
|
ref.watch(windowControlProvider);
|
|
|
|
|
|
|
|
return SafeArea(
|
2023-07-26 22:38:09 -04:00
|
|
|
child: GestureDetector(
|
2023-07-28 20:36:05 -04:00
|
|
|
onTap: () => FocusScope.of(context).requestFocus(_unfocusNode),
|
|
|
|
child: responsiveVisibility(
|
|
|
|
context: context,
|
|
|
|
phone: false,
|
|
|
|
)
|
|
|
|
? buildTablet(context)
|
|
|
|
: buildPhone(context),
|
|
|
|
));
|
|
|
|
}
|
2023-01-08 22:27:33 -05:00
|
|
|
}
|