From 6abfecb4f3470fc170a6a1f965c8184c59466e57 Mon Sep 17 00:00:00 2001 From: otsmr Date: Sun, 30 Mar 2025 21:13:55 +0200 Subject: [PATCH] fix #87 --- lib/src/components/best_friends_selector.dart | 20 ++- .../camera_to_share/share_image_view.dart | 83 +++++---- .../views/chats/chat_item_details_view.dart | 166 +++++++++--------- lib/src/views/chats/search_username_view.dart | 84 ++++----- lib/src/views/settings/diagnostics_view.dart | 112 ++++++------ 5 files changed, 248 insertions(+), 217 deletions(-) diff --git a/lib/src/components/best_friends_selector.dart b/lib/src/components/best_friends_selector.dart index 07564a1..1b2f0f0 100644 --- a/lib/src/components/best_friends_selector.dart +++ b/lib/src/components/best_friends_selector.dart @@ -107,10 +107,13 @@ class UserCheckbox extends StatelessWidget { child: Container( padding: EdgeInsets.symmetric(horizontal: 10, vertical: 0), decoration: BoxDecoration( - border: Border.all( - color: Theme.of(context).colorScheme.outline, - width: 1.0, - ), + color: Theme.of(context).colorScheme.outline.withAlpha(50), + boxShadow: [ + BoxShadow( + blurRadius: 10.9, + color: Color.fromRGBO(0, 0, 0, 0.1), + ), + ], borderRadius: BorderRadius.circular(8.0), ), child: Row( @@ -157,6 +160,15 @@ class UserCheckbox extends StatelessWidget { Expanded(child: Container()), Checkbox( value: isChecked, + side: WidgetStateBorderSide.resolveWith( + (Set states) { + if (states.contains(WidgetState.selected)) { + return BorderSide(width: 0); + } + return BorderSide( + width: 1, color: Theme.of(context).colorScheme.outline); + }, + ), onChanged: (bool? value) { onChanged(user.userId, value ?? false); }, diff --git a/lib/src/views/camera_to_share/share_image_view.dart b/lib/src/views/camera_to_share/share_image_view.dart index 77cd368..aa1efcd 100644 --- a/lib/src/views/camera_to_share/share_image_view.dart +++ b/lib/src/views/camera_to_share/share_image_view.dart @@ -157,45 +157,47 @@ class _ShareImageView extends State { appBar: AppBar( title: Text(context.lang.shareImageTitle), ), - body: Padding( - padding: EdgeInsets.only(bottom: 20, left: 10, top: 20, right: 10), - child: Column( - children: [ - Padding( - padding: EdgeInsets.symmetric(horizontal: 10), - child: TextField( - onChanged: _filterUsers, - decoration: getInputDecoration( - context, context.lang.searchUsernameInput), + body: SafeArea( + child: Padding( + padding: EdgeInsets.only(bottom: 40, left: 10, top: 20, right: 10), + child: Column( + children: [ + Padding( + padding: EdgeInsets.symmetric(horizontal: 10), + child: TextField( + onChanged: _filterUsers, + decoration: getInputDecoration( + context, context.lang.searchUsernameInput), + ), ), - ), - if (showRealTwonlyWarning) const SizedBox(height: 10), - if (showRealTwonlyWarning) - Text( - context.lang.shareImageAllTwonlyWarning, - style: TextStyle(color: Colors.orange), - ), - const SizedBox(height: 10), - BestFriendsSelector( - users: _bestFriends, - selectedUserIds: _selectedUserIds, - maxTotalMediaCounter: maxTotalMediaCounter, - isRealTwonly: widget.isRealTwonly, - updateStatus: updateStatus, - ), - const SizedBox(height: 10), - if (_otherUsers.isNotEmpty) - HeadLineComponent(context.lang.shareImageAllUsers), - Expanded( - child: UserList( - List.from(_otherUsers), - maxTotalMediaCounter, + if (showRealTwonlyWarning) const SizedBox(height: 10), + if (showRealTwonlyWarning) + Text( + context.lang.shareImageAllTwonlyWarning, + style: TextStyle(color: Colors.orange), + ), + const SizedBox(height: 10), + BestFriendsSelector( + users: _bestFriends, selectedUserIds: _selectedUserIds, + maxTotalMediaCounter: maxTotalMediaCounter, isRealTwonly: widget.isRealTwonly, updateStatus: updateStatus, ), - ) - ], + const SizedBox(height: 10), + if (_otherUsers.isNotEmpty) + HeadLineComponent(context.lang.shareImageAllUsers), + Expanded( + child: UserList( + List.from(_otherUsers), + maxTotalMediaCounter, + selectedUserIds: _selectedUserIds, + isRealTwonly: widget.isRealTwonly, + updateStatus: updateStatus, + ), + ) + ], + ), ), ), floatingActionButton: SizedBox( @@ -274,8 +276,8 @@ class UserList extends StatelessWidget { @override Widget build(BuildContext context) { // Step 1: Sort the users alphabetically - users.sort( - (a, b) => getContactDisplayName(a).compareTo(getContactDisplayName(b))); + users + .sort((a, b) => a.lastMessageExchange.compareTo(b.lastMessageExchange)); return ListView.builder( restorationId: 'new_message_users_list', @@ -309,6 +311,15 @@ class UserList extends StatelessWidget { ), trailing: Checkbox( value: selectedUserIds.contains(user.userId), + side: WidgetStateBorderSide.resolveWith( + (Set states) { + if (states.contains(WidgetState.selected)) { + return BorderSide(width: 0); + } + return BorderSide( + width: 1, color: Theme.of(context).colorScheme.outline); + }, + ), onChanged: (bool? value) { if (value == null) return; updateStatus(user.userId, value); diff --git a/lib/src/views/chats/chat_item_details_view.dart b/lib/src/views/chats/chat_item_details_view.dart index 5e44089..0540a18 100644 --- a/lib/src/views/chats/chat_item_details_view.dart +++ b/lib/src/views/chats/chat_item_details_view.dart @@ -251,92 +251,96 @@ class _ChatItemDetailsViewState extends State { ), ), ), - body: Column( - children: [ - Expanded( - child: ListView.builder( - itemCount: messages.length, // Number of items in the list - reverse: true, - itemBuilder: (context, i) { - bool lastMessageFromSameUser = false; - if (i > 0) { - lastMessageFromSameUser = - (messages[i - 1].messageOtherId == null && - messages[i].messageOtherId == null) || - (messages[i - 1].messageOtherId != null && - messages[i].messageOtherId != null); - } - return ChatListEntry( - messages[i], - widget.userid, - lastMessageFromSameUser, - ); - }, + body: SafeArea( + child: Column( + children: [ + Expanded( + child: ListView.builder( + itemCount: messages.length, // Number of items in the list + reverse: true, + itemBuilder: (context, i) { + bool lastMessageFromSameUser = false; + if (i > 0) { + lastMessageFromSameUser = + (messages[i - 1].messageOtherId == null && + messages[i].messageOtherId == null) || + (messages[i - 1].messageOtherId != null && + messages[i].messageOtherId != null); + } + return ChatListEntry( + messages[i], + widget.userid, + lastMessageFromSameUser, + ); + }, + ), ), - ), - Padding( - padding: - const EdgeInsets.only(bottom: 30, left: 20, right: 20, top: 10), - child: Row( - children: [ - Expanded( - child: TextField( - controller: newMessageController, - onChanged: (value) { - currentInputText = value; - setState(() {}); - }, - onSubmitted: (_) { - _sendMessage(); - }, - decoration: InputDecoration( - hintText: context.lang.chatListDetailInput, - contentPadding: - EdgeInsets.symmetric(horizontal: 20, vertical: 10), - border: OutlineInputBorder( - borderRadius: BorderRadius.circular( - 20), // Set the border radius here - borderSide: BorderSide( - color: Theme.of(context).colorScheme.primary, - width: 2.0), // Customize border color and width - ), - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular( - 20.0), // Same radius for focused border - borderSide: BorderSide( - color: Theme.of(context).colorScheme.primary, - width: 2.0), - ), - enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular( - 20.0), // Same radius for enabled border - borderSide: BorderSide(color: Colors.grey, width: 2.0), + Padding( + padding: const EdgeInsets.only( + bottom: 30, left: 20, right: 20, top: 10), + child: Row( + children: [ + Expanded( + child: TextField( + controller: newMessageController, + onChanged: (value) { + currentInputText = value; + setState(() {}); + }, + onSubmitted: (_) { + _sendMessage(); + }, + decoration: InputDecoration( + hintText: context.lang.chatListDetailInput, + contentPadding: + EdgeInsets.symmetric(horizontal: 20, vertical: 10), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular( + 20), // Set the border radius here + borderSide: BorderSide( + color: Theme.of(context).colorScheme.primary, + width: 2.0), // Customize border color and width + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular( + 20.0), // Same radius for focused border + borderSide: BorderSide( + color: Theme.of(context).colorScheme.primary, + width: 2.0), + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular( + 20.0), // Same radius for enabled border + borderSide: + BorderSide(color: Colors.grey, width: 2.0), + ), ), ), ), - ), - SizedBox(width: 8), - (currentInputText != "") - ? IconButton( - icon: FaIcon(FontAwesomeIcons.solidPaperPlane), - onPressed: () { - _sendMessage(); - }, - ) - : IconButton( - icon: FaIcon(FontAwesomeIcons.camera), - onPressed: () { - context - .read() - .updateSendNextMediaTo(widget.userid); - globalUpdateOfHomeViewPageIndex(0); - Navigator.popUntil(context, (route) => route.isFirst); - }, - ) - ], + SizedBox(width: 8), + (currentInputText != "") + ? IconButton( + icon: FaIcon(FontAwesomeIcons.solidPaperPlane), + onPressed: () { + _sendMessage(); + }, + ) + : IconButton( + icon: FaIcon(FontAwesomeIcons.camera), + onPressed: () { + context + .read() + .updateSendNextMediaTo(widget.userid); + globalUpdateOfHomeViewPageIndex(0); + Navigator.popUntil( + context, (route) => route.isFirst); + }, + ) + ], + ), ), - ), - ], + ], + ), ), ); } diff --git a/lib/src/views/chats/search_username_view.dart b/lib/src/views/chats/search_username_view.dart index 1fa4280..90551b6 100644 --- a/lib/src/views/chats/search_username_view.dart +++ b/lib/src/views/chats/search_username_view.dart @@ -106,49 +106,51 @@ class _SearchUsernameView extends State { appBar: AppBar( title: Text(context.lang.searchUsernameTitle), ), - body: Padding( - padding: EdgeInsets.only(bottom: 20, left: 10, top: 20, right: 10), - child: Column( - children: [ - Padding( - padding: EdgeInsets.symmetric(horizontal: 10), - child: TextField( - onSubmitted: (_) { - _addNewUser(context); + body: SafeArea( + child: Padding( + padding: EdgeInsets.only(bottom: 20, left: 10, top: 20, right: 10), + child: Column( + children: [ + Padding( + padding: EdgeInsets.symmetric(horizontal: 10), + child: TextField( + onSubmitted: (_) { + _addNewUser(context); + }, + controller: searchUserName, + decoration: + getInputDecoration(context.lang.searchUsernameInput), + ), + ), + const SizedBox(height: 20), + OutlinedButton.icon( + icon: Icon(Icons.qr_code), + onPressed: () { + showAlertDialog(context, "Coming soon", + "This feature is not yet implemented!"); }, - controller: searchUserName, - decoration: - getInputDecoration(context.lang.searchUsernameInput), + label: Text(context.lang.searchUsernameQrCodeBtn), ), - ), - const SizedBox(height: 20), - OutlinedButton.icon( - icon: Icon(Icons.qr_code), - onPressed: () { - showAlertDialog(context, "Coming soon", - "This feature is not yet implemented!"); - }, - label: Text(context.lang.searchUsernameQrCodeBtn), - ), - SizedBox(height: 30), - if (hasRequestedUsers) - HeadLineComponent( - context.lang.searchUsernameNewFollowerTitle, - ), - StreamBuilder( - stream: contacts, - builder: (context, snapshot) { - if (!snapshot.hasData || - snapshot.data == null || - snapshot.data!.isEmpty) { - hasRequestedUsers = false; - return Container(); - } - hasRequestedUsers = true; - return Expanded(child: ContactsListView(snapshot.data!)); - }, - ) - ], + SizedBox(height: 30), + if (hasRequestedUsers) + HeadLineComponent( + context.lang.searchUsernameNewFollowerTitle, + ), + StreamBuilder( + stream: contacts, + builder: (context, snapshot) { + if (!snapshot.hasData || + snapshot.data == null || + snapshot.data!.isEmpty) { + hasRequestedUsers = false; + return Container(); + } + hasRequestedUsers = true; + return Expanded(child: ContactsListView(snapshot.data!)); + }, + ) + ], + ), ), ), floatingActionButton: Padding( diff --git a/lib/src/views/settings/diagnostics_view.dart b/lib/src/views/settings/diagnostics_view.dart index b141d7c..90ff823 100644 --- a/lib/src/views/settings/diagnostics_view.dart +++ b/lib/src/views/settings/diagnostics_view.dart @@ -9,67 +9,69 @@ class DiagnosticsView extends StatelessWidget { @override Widget build(BuildContext context) { - return FutureBuilder( - future: _loadLogFile(), - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.waiting) { - return const Center(child: CircularProgressIndicator()); - } else if (snapshot.hasError) { - return Center(child: Text('Error: ${snapshot.error}')); - } else { - final logText = snapshot.data ?? ''; + return SafeArea( + child: FutureBuilder( + future: _loadLogFile(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const Center(child: CircularProgressIndicator()); + } else if (snapshot.hasError) { + return Center(child: Text('Error: ${snapshot.error}')); + } else { + final logText = snapshot.data ?? ''; - return Scaffold( - appBar: AppBar(title: const Text('Diagnostics')), - body: Column( - children: [ - Expanded( - child: SingleChildScrollView( + return Scaffold( + appBar: AppBar(title: const Text('Diagnostics')), + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + padding: const EdgeInsets.all(16.0), + child: Text(logText), + ), + ), + Padding( padding: const EdgeInsets.all(16.0), - child: Text(logText), - ), - ), - Padding( - padding: const EdgeInsets.all(16.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - TextButton( - onPressed: () { - Clipboard.setData(ClipboardData(text: logText)); - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text('Log copied to clipboard!')), - ); - }, - child: const Text('Copy All Text'), - ), - TextButton( - onPressed: () async { - if (await deleteLogFile()) { - if (!context.mounted) return; + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + TextButton( + onPressed: () { + Clipboard.setData(ClipboardData(text: logText)); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( - content: Text('Log file deleted!')), + content: Text('Log copied to clipboard!')), ); - } else { - if (!context.mounted) return; - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text('Log file does not exist.')), - ); - } - }, - child: const Text('Delete Log File'), - ), - ], + }, + child: const Text('Copy All Text'), + ), + TextButton( + onPressed: () async { + if (await deleteLogFile()) { + if (!context.mounted) return; + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Log file deleted!')), + ); + } else { + if (!context.mounted) return; + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Log file does not exist.')), + ); + } + }, + child: const Text('Delete Log File'), + ), + ], + ), ), - ), - ], - ), - ); - } - }, + ], + ), + ); + } + }, + ), ); }