This commit is contained in:
otsmr 2025-03-30 21:13:55 +02:00
parent f485366719
commit 6abfecb4f3
5 changed files with 248 additions and 217 deletions

View file

@ -107,10 +107,13 @@ class UserCheckbox extends StatelessWidget {
child: Container( child: Container(
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 0), padding: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all( color: Theme.of(context).colorScheme.outline.withAlpha(50),
color: Theme.of(context).colorScheme.outline, boxShadow: [
width: 1.0, BoxShadow(
), blurRadius: 10.9,
color: Color.fromRGBO(0, 0, 0, 0.1),
),
],
borderRadius: BorderRadius.circular(8.0), borderRadius: BorderRadius.circular(8.0),
), ),
child: Row( child: Row(
@ -157,6 +160,15 @@ class UserCheckbox extends StatelessWidget {
Expanded(child: Container()), Expanded(child: Container()),
Checkbox( Checkbox(
value: isChecked, 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: (bool? value) {
onChanged(user.userId, value ?? false); onChanged(user.userId, value ?? false);
}, },

View file

@ -157,45 +157,47 @@ class _ShareImageView extends State<ShareImageView> {
appBar: AppBar( appBar: AppBar(
title: Text(context.lang.shareImageTitle), title: Text(context.lang.shareImageTitle),
), ),
body: Padding( body: SafeArea(
padding: EdgeInsets.only(bottom: 20, left: 10, top: 20, right: 10), child: Padding(
child: Column( padding: EdgeInsets.only(bottom: 40, left: 10, top: 20, right: 10),
children: [ child: Column(
Padding( children: [
padding: EdgeInsets.symmetric(horizontal: 10), Padding(
child: TextField( padding: EdgeInsets.symmetric(horizontal: 10),
onChanged: _filterUsers, child: TextField(
decoration: getInputDecoration( onChanged: _filterUsers,
context, context.lang.searchUsernameInput), decoration: getInputDecoration(
context, context.lang.searchUsernameInput),
),
), ),
), if (showRealTwonlyWarning) const SizedBox(height: 10),
if (showRealTwonlyWarning) const SizedBox(height: 10), if (showRealTwonlyWarning)
if (showRealTwonlyWarning) Text(
Text( context.lang.shareImageAllTwonlyWarning,
context.lang.shareImageAllTwonlyWarning, style: TextStyle(color: Colors.orange),
style: TextStyle(color: Colors.orange), ),
), const SizedBox(height: 10),
const SizedBox(height: 10), BestFriendsSelector(
BestFriendsSelector( users: _bestFriends,
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, selectedUserIds: _selectedUserIds,
maxTotalMediaCounter: maxTotalMediaCounter,
isRealTwonly: widget.isRealTwonly, isRealTwonly: widget.isRealTwonly,
updateStatus: updateStatus, 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( floatingActionButton: SizedBox(
@ -274,8 +276,8 @@ class UserList extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// Step 1: Sort the users alphabetically // Step 1: Sort the users alphabetically
users.sort( users
(a, b) => getContactDisplayName(a).compareTo(getContactDisplayName(b))); .sort((a, b) => a.lastMessageExchange.compareTo(b.lastMessageExchange));
return ListView.builder( return ListView.builder(
restorationId: 'new_message_users_list', restorationId: 'new_message_users_list',
@ -309,6 +311,15 @@ class UserList extends StatelessWidget {
), ),
trailing: Checkbox( trailing: Checkbox(
value: selectedUserIds.contains(user.userId), 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) { onChanged: (bool? value) {
if (value == null) return; if (value == null) return;
updateStatus(user.userId, value); updateStatus(user.userId, value);

View file

@ -251,92 +251,96 @@ class _ChatItemDetailsViewState extends State<ChatItemDetailsView> {
), ),
), ),
), ),
body: Column( body: SafeArea(
children: [ child: Column(
Expanded( children: [
child: ListView.builder( Expanded(
itemCount: messages.length, // Number of items in the list child: ListView.builder(
reverse: true, itemCount: messages.length, // Number of items in the list
itemBuilder: (context, i) { reverse: true,
bool lastMessageFromSameUser = false; itemBuilder: (context, i) {
if (i > 0) { bool lastMessageFromSameUser = false;
lastMessageFromSameUser = if (i > 0) {
(messages[i - 1].messageOtherId == null && lastMessageFromSameUser =
messages[i].messageOtherId == null) || (messages[i - 1].messageOtherId == null &&
(messages[i - 1].messageOtherId != null && messages[i].messageOtherId == null) ||
messages[i].messageOtherId != null); (messages[i - 1].messageOtherId != null &&
} messages[i].messageOtherId != null);
return ChatListEntry( }
messages[i], return ChatListEntry(
widget.userid, messages[i],
lastMessageFromSameUser, widget.userid,
); lastMessageFromSameUser,
}, );
},
),
), ),
), Padding(
Padding( padding: const EdgeInsets.only(
padding: bottom: 30, left: 20, right: 20, top: 10),
const EdgeInsets.only(bottom: 30, left: 20, right: 20, top: 10), child: Row(
child: Row( children: [
children: [ Expanded(
Expanded( child: TextField(
child: TextField( controller: newMessageController,
controller: newMessageController, onChanged: (value) {
onChanged: (value) { currentInputText = value;
currentInputText = value; setState(() {});
setState(() {}); },
}, onSubmitted: (_) {
onSubmitted: (_) { _sendMessage();
_sendMessage(); },
}, decoration: InputDecoration(
decoration: InputDecoration( hintText: context.lang.chatListDetailInput,
hintText: context.lang.chatListDetailInput, contentPadding:
contentPadding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
EdgeInsets.symmetric(horizontal: 20, vertical: 10), border: OutlineInputBorder(
border: OutlineInputBorder( borderRadius: BorderRadius.circular(
borderRadius: BorderRadius.circular( 20), // Set the border radius here
20), // Set the border radius here borderSide: BorderSide(
borderSide: BorderSide( color: Theme.of(context).colorScheme.primary,
color: Theme.of(context).colorScheme.primary, width: 2.0), // Customize border color and width
width: 2.0), // Customize border color and width ),
), focusedBorder: OutlineInputBorder(
focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(
borderRadius: BorderRadius.circular( 20.0), // Same radius for focused border
20.0), // Same radius for focused border borderSide: BorderSide(
borderSide: BorderSide( color: Theme.of(context).colorScheme.primary,
color: Theme.of(context).colorScheme.primary, width: 2.0),
width: 2.0), ),
), enabledBorder: OutlineInputBorder(
enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(
borderRadius: BorderRadius.circular( 20.0), // Same radius for enabled border
20.0), // Same radius for enabled border borderSide:
borderSide: BorderSide(color: Colors.grey, width: 2.0), BorderSide(color: Colors.grey, width: 2.0),
),
), ),
), ),
), ),
), SizedBox(width: 8),
SizedBox(width: 8), (currentInputText != "")
(currentInputText != "") ? IconButton(
? IconButton( icon: FaIcon(FontAwesomeIcons.solidPaperPlane),
icon: FaIcon(FontAwesomeIcons.solidPaperPlane), onPressed: () {
onPressed: () { _sendMessage();
_sendMessage(); },
}, )
) : IconButton(
: IconButton( icon: FaIcon(FontAwesomeIcons.camera),
icon: FaIcon(FontAwesomeIcons.camera), onPressed: () {
onPressed: () { context
context .read<SendNextMediaTo>()
.read<SendNextMediaTo>() .updateSendNextMediaTo(widget.userid);
.updateSendNextMediaTo(widget.userid); globalUpdateOfHomeViewPageIndex(0);
globalUpdateOfHomeViewPageIndex(0); Navigator.popUntil(
Navigator.popUntil(context, (route) => route.isFirst); context, (route) => route.isFirst);
}, },
) )
], ],
),
), ),
), ],
], ),
), ),
); );
} }

View file

@ -106,49 +106,51 @@ class _SearchUsernameView extends State<SearchUsernameView> {
appBar: AppBar( appBar: AppBar(
title: Text(context.lang.searchUsernameTitle), title: Text(context.lang.searchUsernameTitle),
), ),
body: Padding( body: SafeArea(
padding: EdgeInsets.only(bottom: 20, left: 10, top: 20, right: 10), child: Padding(
child: Column( padding: EdgeInsets.only(bottom: 20, left: 10, top: 20, right: 10),
children: [ child: Column(
Padding( children: [
padding: EdgeInsets.symmetric(horizontal: 10), Padding(
child: TextField( padding: EdgeInsets.symmetric(horizontal: 10),
onSubmitted: (_) { child: TextField(
_addNewUser(context); 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, label: Text(context.lang.searchUsernameQrCodeBtn),
decoration:
getInputDecoration(context.lang.searchUsernameInput),
), ),
), SizedBox(height: 30),
const SizedBox(height: 20), if (hasRequestedUsers)
OutlinedButton.icon( HeadLineComponent(
icon: Icon(Icons.qr_code), context.lang.searchUsernameNewFollowerTitle,
onPressed: () { ),
showAlertDialog(context, "Coming soon", StreamBuilder(
"This feature is not yet implemented!"); stream: contacts,
}, builder: (context, snapshot) {
label: Text(context.lang.searchUsernameQrCodeBtn), if (!snapshot.hasData ||
), snapshot.data == null ||
SizedBox(height: 30), snapshot.data!.isEmpty) {
if (hasRequestedUsers) hasRequestedUsers = false;
HeadLineComponent( return Container();
context.lang.searchUsernameNewFollowerTitle, }
), hasRequestedUsers = true;
StreamBuilder( return Expanded(child: ContactsListView(snapshot.data!));
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( floatingActionButton: Padding(

View file

@ -9,67 +9,69 @@ class DiagnosticsView extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return FutureBuilder<String>( return SafeArea(
future: _loadLogFile(), child: FutureBuilder<String>(
builder: (context, snapshot) { future: _loadLogFile(),
if (snapshot.connectionState == ConnectionState.waiting) { builder: (context, snapshot) {
return const Center(child: CircularProgressIndicator()); if (snapshot.connectionState == ConnectionState.waiting) {
} else if (snapshot.hasError) { return const Center(child: CircularProgressIndicator());
return Center(child: Text('Error: ${snapshot.error}')); } else if (snapshot.hasError) {
} else { return Center(child: Text('Error: ${snapshot.error}'));
final logText = snapshot.data ?? ''; } else {
final logText = snapshot.data ?? '';
return Scaffold( return Scaffold(
appBar: AppBar(title: const Text('Diagnostics')), appBar: AppBar(title: const Text('Diagnostics')),
body: Column( body: Column(
children: [ children: [
Expanded( Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Text(logText),
),
),
Padding(
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
child: Text(logText), child: Row(
), mainAxisAlignment: MainAxisAlignment.spaceBetween,
), children: [
Padding( TextButton(
padding: const EdgeInsets.all(16.0), onPressed: () {
child: Row( Clipboard.setData(ClipboardData(text: logText));
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;
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
const SnackBar( const SnackBar(
content: Text('Log file deleted!')), content: Text('Log copied to clipboard!')),
); );
} else { },
if (!context.mounted) return; child: const Text('Copy All Text'),
ScaffoldMessenger.of(context).showSnackBar( ),
const SnackBar( TextButton(
content: Text('Log file does not exist.')), onPressed: () async {
); if (await deleteLogFile()) {
} if (!context.mounted) return;
}, ScaffoldMessenger.of(context).showSnackBar(
child: const Text('Delete Log File'), 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'),
),
],
),
), ),
), ],
], ),
), );
); }
} },
}, ),
); );
} }