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(
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);
},

View file

@ -157,45 +157,47 @@ class _ShareImageView extends State<ShareImageView> {
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);

View file

@ -251,92 +251,96 @@ class _ChatItemDetailsViewState extends State<ChatItemDetailsView> {
),
),
),
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<SendNextMediaTo>()
.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<SendNextMediaTo>()
.updateSendNextMediaTo(widget.userid);
globalUpdateOfHomeViewPageIndex(0);
Navigator.popUntil(
context, (route) => route.isFirst);
},
)
],
),
),
),
],
],
),
),
);
}

View file

@ -106,49 +106,51 @@ class _SearchUsernameView extends State<SearchUsernameView> {
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(

View file

@ -9,67 +9,69 @@ class DiagnosticsView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FutureBuilder<String>(
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<String>(
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'),
),
],
),
),
),
],
),
);
}
},
],
),
);
}
},
),
);
}