ui cleanups

This commit is contained in:
Christien Rioux 2024-06-24 23:44:08 +00:00
parent 01ba275c71
commit 8c89ce91cf
8 changed files with 175 additions and 136 deletions

View File

@ -1,37 +0,0 @@
import 'dart:async';
import 'package:async_tools/async_tools.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:veilid_support/veilid_support.dart';
import '../../account_manager/account_manager.dart';
class ActiveAccountPageControllerWrapper {
ActiveAccountPageControllerWrapper(Locator locator, int initialPage) {
pageController = PageController(initialPage: initialPage, keepPage: false);
final activeLocalAccountCubit = locator<ActiveLocalAccountCubit>();
_subscription =
activeLocalAccountCubit.stream.listen((activeLocalAccountRecordKey) {
singleFuture(this, () async {
final localAccounts = locator<LocalAccountsCubit>().state;
final activeIndex = localAccounts.indexWhere(
(x) => x.superIdentity.recordKey == activeLocalAccountRecordKey);
if (pageController.page == activeIndex) {
return;
}
await pageController.animateToPage(activeIndex,
duration: const Duration(milliseconds: 250),
curve: Curves.fastOutSlowIn);
});
});
}
void dispose() {
unawaited(_subscription.cancel());
}
late PageController pageController;
late StreamSubscription<TypedKey?> _subscription;
}

View File

@ -1,4 +1,3 @@
export 'active_account_page_controller_wrapper.dart';
export 'drawer_menu/drawer_menu.dart';
export 'home_account_invalid.dart';
export 'home_account_locked.dart';

View File

@ -1,4 +1,5 @@
import 'package:awesome_extensions/awesome_extensions.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_translate/flutter_translate.dart';
@ -35,27 +36,32 @@ class _HomeAccountReadyMainState extends State<HomeAccountReadyMain> {
final theme = Theme.of(context);
final scale = theme.extension<ScaleScheme>()!;
return Column(children: <Widget>[
Row(children: [
IconButton(
icon: const Icon(Icons.menu),
color: scale.secondaryScale.borderText,
constraints: const BoxConstraints.expand(height: 64, width: 64),
style: ButtonStyle(
backgroundColor:
WidgetStateProperty.all(scale.primaryScale.hoverBorder),
shape: WidgetStateProperty.all(const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(16))))),
tooltip: translate('menu.settings_tooltip'),
onPressed: () async {
final ctrl = context.read<ZoomDrawerController>();
await ctrl.toggle?.call();
//await GoRouterHelper(context).push('/settings');
}).paddingLTRB(0, 0, 8, 0),
ProfileWidget(profile: profile).expanded(),
]).paddingAll(8),
const MainPager().expanded()
]);
return ColoredBox(
color: scale.primaryScale.subtleBorder,
child: Column(children: <Widget>[
Row(children: [
IconButton(
icon: const Icon(Icons.menu),
color: scale.secondaryScale.borderText,
constraints:
const BoxConstraints.expand(height: 64, width: 64),
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all(
scale.primaryScale.hoverBorder),
shape: WidgetStateProperty.all(
const RoundedRectangleBorder(
borderRadius:
BorderRadius.all(Radius.circular(16))))),
tooltip: translate('menu.settings_tooltip'),
onPressed: () async {
final ctrl = context.read<ZoomDrawerController>();
await ctrl.toggle?.call();
//await GoRouterHelper(context).push('/settings');
}).paddingLTRB(0, 0, 8, 0),
ProfileWidget(profile: profile).expanded(),
]).paddingAll(8),
MainPager(key: _mainPagerKey).expanded()
]));
});
Widget buildPhone(BuildContext context) =>
@ -107,4 +113,7 @@ class _HomeAccountReadyMainState extends State<HomeAccountReadyMain> {
)
? buildTablet(context)
: buildPhone(context);
////////////////////////////////////////////////////////////////////////////
final _mainPagerKey = GlobalKey(debugLabel: '_mainPagerKey');
}

View File

@ -28,25 +28,6 @@ class MainPager extends StatefulWidget {
class MainPagerState extends State<MainPager> with TickerProviderStateMixin {
//////////////////////////////////////////////////////////////////
var _currentPage = 0;
final pageController = PreloadPageController();
final _selectedIconList = <IconData>[Icons.person, Icons.chat];
// final _unselectedIconList = <IconData>[
// Icons.chat_outlined,
// Icons.person_outlined
// ];
final _fabIconList = <IconData>[
Icons.person_add_sharp,
Icons.add_comment_sharp,
];
final _bottomLabelList = <String>[
translate('pager.contacts'),
translate('pager.chats'),
];
//////////////////////////////////////////////////////////////////
@override
void initState() {
super.initState();
@ -124,10 +105,10 @@ class MainPagerState extends State<MainPager> with TickerProviderStateMixin {
}
Widget _bottomSheetBuilder(BuildContext sheetContext, BuildContext context) {
if (_currentPage == 0) {
if (currentPage == 0) {
// New contact invitation
return newContactBottomSheetBuilder(sheetContext, context);
} else if (_currentPage == 1) {
} else if (currentPage == 1) {
// New chat
return newChatBottomSheetBuilder(sheetContext, context);
} else {
@ -148,11 +129,12 @@ class MainPagerState extends State<MainPager> with TickerProviderStateMixin {
body: NotificationListener<ScrollNotification>(
onNotification: onScrollNotification,
child: PreloadPageView(
key: _pageViewKey,
controller: pageController,
preloadPagesCount: 2,
onPageChanged: (index) {
setState(() {
_currentPage = index;
currentPage = index;
});
},
children: const [
@ -176,7 +158,7 @@ class MainPagerState extends State<MainPager> with TickerProviderStateMixin {
items: _buildBottomBarItems(),
hasNotch: true,
fabLocation: StylishBarFabLocation.end,
currentIndex: _currentPage,
currentIndex: currentPage,
onTap: (index) async {
await pageController.animateToPage(index,
duration: 250.ms, curve: Curves.easeInOut);
@ -189,7 +171,7 @@ class MainPagerState extends State<MainPager> with TickerProviderStateMixin {
foregroundColor: scale.secondaryScale.borderText,
backgroundColor: scale.secondaryScale.hoverBorder,
builder: (context) => Icon(
_fabIconList[_currentPage],
_fabIconList[currentPage],
color: scale.secondaryScale.borderText,
),
bottomSheetBuilder: (sheetContext) =>
@ -198,10 +180,33 @@ class MainPagerState extends State<MainPager> with TickerProviderStateMixin {
);
}
//////////////////////////////////////////////////////////////////
final _selectedIconList = <IconData>[Icons.person, Icons.chat];
// final _unselectedIconList = <IconData>[
// Icons.chat_outlined,
// Icons.person_outlined
// ];
final _fabIconList = <IconData>[
Icons.person_add_sharp,
Icons.add_comment_sharp,
];
final _bottomLabelList = <String>[
translate('pager.contacts'),
translate('pager.chats'),
];
final _pageViewKey = GlobalKey(debugLabel: '_pageViewKey');
// key-accessible controller
int currentPage = 0;
final pageController = PreloadPageController();
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<PreloadPageController>(
'pageController', pageController));
properties
..add(IntProperty('currentPage', currentPage))
..add(DiagnosticsProperty<PreloadPageController>(
'pageController', pageController));
}
}

View File

@ -1,16 +1,16 @@
import 'dart:math';
import 'package:async_tools/async_tools.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_zoom_drawer/flutter_zoom_drawer.dart';
import 'package:provider/provider.dart';
import 'package:transitioned_indexed_stack/transitioned_indexed_stack.dart';
import 'package:veilid_support/veilid_support.dart';
import '../../account_manager/account_manager.dart';
import '../../chat/chat.dart';
import '../../theme/theme.dart';
import '../../tools/tools.dart';
import 'active_account_page_controller_wrapper.dart';
import 'drawer_menu/drawer_menu.dart';
import 'home_account_invalid.dart';
import 'home_account_locked.dart';
@ -23,34 +23,71 @@ class HomeScreen extends StatefulWidget {
@override
HomeScreenState createState() => HomeScreenState();
static HomeScreenState? of(BuildContext context) =>
context.findAncestorStateOfType<HomeScreenState>();
}
class HomeScreenState extends State<HomeScreen> {
class HomeScreenState extends State<HomeScreen>
with SingleTickerProviderStateMixin {
@override
void initState() {
// Chat animation setup (open in phone mode)
_chatAnimationController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 250),
);
_chatAnimation = Tween<Offset>(
begin: const Offset(1, 0),
end: Offset.zero,
).animate(CurvedAnimation(
parent: _chatAnimationController,
curve: Curves.easeInOut,
));
// Account animation setup
super.initState();
}
@override
void dispose() {
_chatAnimationController.dispose();
super.dispose();
}
Widget _buildAccountReadyDeviceSpecific(BuildContext context) {
final hasActiveChat = context.watch<ActiveChatCubit>().state != null;
if (responsiveVisibility(
context: context,
tablet: false,
tabletLandscape: false,
desktop: false)) {
if (hasActiveChat) {
return const HomeAccountReadyChat();
}
return BlocConsumer<ActiveChatCubit, TypedKey?>(
listener: (context, activeChat) {
final hasActiveChat = activeChat != null;
if (hasActiveChat) {
_chatAnimationController.forward();
} else {
_chatAnimationController.reset();
}
},
builder: (context, activeChat) => Stack(
children: <Widget>[
const HomeAccountReadyMain(),
Offstage(
offstage: activeChat == null,
child: SlideTransition(
position: _chatAnimation,
child: const HomeAccountReadyChat())),
],
));
}
return const HomeAccountReadyMain();
}
Widget _buildAccount(BuildContext context, TypedKey superIdentityRecordKey,
Widget _buildAccountPage(
BuildContext context,
TypedKey superIdentityRecordKey,
PerAccountCollectionState perAccountCollectionState) {
switch (perAccountCollectionState.accountInfo.status) {
case AccountInfoStatus.accountInvalid:
@ -81,38 +118,25 @@ class HomeScreenState extends State<HomeScreen> {
return const HomeNoActive();
}
return Provider<ActiveAccountPageControllerWrapper>(
lazy: false,
create: (context) =>
ActiveAccountPageControllerWrapper(context.read, activeIndex),
dispose: (context, value) {
value.dispose();
},
child: Builder(
builder: (context) => PageView.builder(
onPageChanged: (idx) {
singleFuture(this, () async {
await AccountRepository.instance.switchToAccount(
localAccounts[idx].superIdentity.recordKey);
});
},
controller: context
.read<ActiveAccountPageControllerWrapper>()
.pageController,
itemCount: localAccounts.length,
itemBuilder: (context, index) {
final superIdentityRecordKey =
localAccounts[index].superIdentity.recordKey;
final perAccountCollectionState =
perAccountCollectionBlocMapState
.get(superIdentityRecordKey);
if (perAccountCollectionState == null) {
return HomeAccountMissing(
key: ValueKey(superIdentityRecordKey));
}
return _buildAccount(context, superIdentityRecordKey,
perAccountCollectionState);
})));
final accountPages = <Widget>[];
for (var i = 0; i < localAccounts.length; i++) {
final superIdentityRecordKey = localAccounts[i].superIdentity.recordKey;
final perAccountCollectionState =
perAccountCollectionBlocMapState.get(superIdentityRecordKey);
if (perAccountCollectionState == null) {
return HomeAccountMissing(key: ValueKey(superIdentityRecordKey));
}
final accountPage = _buildAccountPage(
context, superIdentityRecordKey, perAccountCollectionState);
accountPages.add(KeyedSubtree.wrap(accountPage, i));
}
return SlideIndexedStack(
index: activeIndex,
beginSlideOffset: const Offset(1, 0),
children: accountPages,
);
}
@override
@ -134,15 +158,20 @@ class HomeScreenState extends State<HomeScreen> {
child: ZoomDrawer(
controller: _zoomDrawerController,
//menuBackgroundColor: Colors.transparent,
menuScreen: const DrawerMenu(),
mainScreen: DecoratedBox(
decoration: BoxDecoration(
color: scale.primaryScale.activeElementBackground),
child: Provider<ZoomDrawerController>.value(
value: _zoomDrawerController,
child: Builder(builder: _buildAccountPageView))),
menuScreen: Builder(builder: (context) {
final zoomDrawer = ZoomDrawer.of(context);
zoomDrawer!.stateNotifier.addListener(() {
if (zoomDrawer.isOpen()) {
FocusManager.instance.primaryFocus?.unfocus();
}
});
return const DrawerMenu();
}),
mainScreen: Provider<ZoomDrawerController>.value(
value: _zoomDrawerController,
child: Builder(builder: _buildAccountPageView)),
borderRadius: 24,
showShadow: true,
//showShadow: false,
angle: 0,
drawerShadowsBackgroundColor: theme.shadowColor,
mainScreenOverlayColor: theme.shadowColor.withAlpha(0x3F),
@ -151,10 +180,15 @@ class HomeScreenState extends State<HomeScreen> {
// reverseDuration: const Duration(milliseconds: 250),
menuScreenTapClose: true,
mainScreenTapClose: true,
//disableDragGesture: false,
mainScreenScale: .25,
slideWidth: min(360, MediaQuery.of(context).size.width * 0.9),
)));
}
////////////////////////////////////////////////////////////////////////////
final _zoomDrawerController = ZoomDrawerController();
late final Animation<Offset> _chatAnimation;
late final AnimationController _chatAnimationController;
}

View File

@ -2,6 +2,12 @@ import 'dart:io' show Platform;
import 'package:veilid/veilid.dart';
// ignore: do_not_use_environment
const bool _kReleaseMode = bool.fromEnvironment('dart.vm.product');
// ignore: do_not_use_environment
const bool _kProfileMode = bool.fromEnvironment('dart.vm.profile');
const bool _kDebugMode = !_kReleaseMode && !_kProfileMode;
Map<String, dynamic> getDefaultVeilidPlatformConfig(
bool isWeb, String appName) {
final ignoreLogTargetsStr =
@ -16,7 +22,9 @@ Map<String, dynamic> getDefaultVeilidPlatformConfig(
logging: VeilidWASMConfigLogging(
performance: VeilidWASMConfigLoggingPerformance(
enabled: true,
level: VeilidConfigLogLevel.debug,
level: _kDebugMode
? VeilidConfigLogLevel.debug
: VeilidConfigLogLevel.info,
logsInTimings: true,
logsInConsole: false,
ignoreLogTargets: ignoreLogTargets),
@ -29,8 +37,11 @@ Map<String, dynamic> getDefaultVeilidPlatformConfig(
return VeilidFFIConfig(
logging: VeilidFFIConfigLogging(
terminal: VeilidFFIConfigLoggingTerminal(
enabled: false,
level: VeilidConfigLogLevel.debug,
enabled:
_kDebugMode && (Platform.isIOS || Platform.isAndroid),
level: _kDebugMode
? VeilidConfigLogLevel.debug
: VeilidConfigLogLevel.info,
ignoreLogTargets: ignoreLogTargets),
otlp: VeilidFFIConfigLoggingOtlp(
enabled: false,

View File

@ -17,6 +17,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "6.4.1"
animated_switcher_transitions:
dependency: "direct main"
description:
name: animated_switcher_transitions
sha256: "0f3ef1b46ab3f0b5efe784dcff55bbeabdc75a3b9bcbefbf2315468c9cec87c3"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
animated_theme_switcher:
dependency: "direct main"
description:
@ -1399,6 +1407,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.1"
transitioned_indexed_stack:
dependency: "direct main"
description:
name: transitioned_indexed_stack
sha256: "8023abb5efe72e6d40cc3775fb03d7504c32ac918ec2ce7f9ba6804753820259"
url: "https://pub.dev"
source: hosted
version: "1.0.2"
typed_data:
dependency: transitive
description:

View File

@ -8,6 +8,7 @@ environment:
flutter: '>=3.22.1'
dependencies:
animated_switcher_transitions: ^1.0.0
animated_theme_switcher: ^2.0.10
ansicolor: ^2.0.2
archive: ^3.6.1
@ -83,6 +84,7 @@ dependencies:
stack_trace: ^1.11.1
stream_transform: ^2.1.0
stylish_bottom_bar: ^1.1.0
transitioned_indexed_stack: ^1.0.2
uuid: ^4.4.0
veilid:
# veilid: ^0.0.1