mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-07-29 14:58:44 +10:00
Merge branch 'dev' into update-pacox-multibyte
This commit is contained in:
@@ -111,24 +111,26 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
PopupMenuItem(
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.logout, color: Colors.red),
|
||||
Icon(
|
||||
Icons.logout,
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(context.l10n.common_disconnect),
|
||||
],
|
||||
),
|
||||
onTap: () => _disconnect(context),
|
||||
),
|
||||
if (_communities.isNotEmpty)
|
||||
PopupMenuItem(
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.groups),
|
||||
const SizedBox(width: 8),
|
||||
Text(context.l10n.community_manageCommunities),
|
||||
],
|
||||
),
|
||||
onTap: () => _showManageCommunitiesDialog(context),
|
||||
PopupMenuItem(
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.groups),
|
||||
const SizedBox(width: 8),
|
||||
Text(context.l10n.community_manageCommunities),
|
||||
],
|
||||
),
|
||||
onTap: () => _showManageCommunitiesDialog(context),
|
||||
),
|
||||
PopupMenuItem(
|
||||
child: Row(
|
||||
children: [
|
||||
@@ -241,32 +243,21 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
),
|
||||
Expanded(
|
||||
child: filteredChannels.isEmpty
|
||||
? ListView(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height - 300,
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.search_off,
|
||||
size: 64,
|
||||
color: Colors.grey[400],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
context.l10n.channels_noChannelsFound,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.grey[600],
|
||||
),
|
||||
),
|
||||
],
|
||||
? LayoutBuilder(
|
||||
builder: (context, constraints) => ListView(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
children: [
|
||||
ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
minHeight: constraints.maxHeight,
|
||||
),
|
||||
child: EmptyState(
|
||||
icon: Icons.search_off,
|
||||
title: context.l10n.channels_noChannelsFound,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
)
|
||||
: (viewState.channelsSortOption ==
|
||||
ChannelSortOption.manual &&
|
||||
@@ -355,6 +346,9 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
int? dragIndex,
|
||||
}) {
|
||||
final unreadCount = connector.getUnreadCountForChannel(channel);
|
||||
final isMuted = context.watch<AppSettingsService>().isChannelMuted(
|
||||
channel.name,
|
||||
);
|
||||
|
||||
// Determine icon and colors based on channel type
|
||||
IconData icon;
|
||||
@@ -447,37 +441,45 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
trailing: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (isMuted) ...[
|
||||
Icon(
|
||||
Icons.notifications_off,
|
||||
size: 14,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
],
|
||||
if (unreadCount > 0) ...[
|
||||
UnreadBadge(count: unreadCount),
|
||||
const SizedBox(width: 4),
|
||||
],
|
||||
if (showDragHandle && dragIndex != null)
|
||||
ReorderableDelayedDragStartListener(
|
||||
ReorderableDragStartListener(
|
||||
index: dragIndex,
|
||||
child: Icon(
|
||||
Icons.drag_handle,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Icon(
|
||||
Icons.drag_handle,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
onTap: () async {
|
||||
onTap: () {
|
||||
final unread = connector.getUnreadCountForChannelIndex(
|
||||
channel.index,
|
||||
);
|
||||
connector.markChannelRead(channel.index);
|
||||
await Future.delayed(const Duration(milliseconds: 50));
|
||||
if (context.mounted) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ChannelChatScreen(
|
||||
channel: channel,
|
||||
initialUnreadCount: unread,
|
||||
),
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ChannelChatScreen(
|
||||
channel: channel,
|
||||
initialUnreadCount: unread,
|
||||
),
|
||||
);
|
||||
}
|
||||
),
|
||||
);
|
||||
},
|
||||
onLongPress: () => _showChannelActions(
|
||||
context,
|
||||
@@ -538,10 +540,15 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.delete_outline, color: Colors.red),
|
||||
leading: Icon(
|
||||
Icons.delete_outline,
|
||||
color: Theme.of(sheetContext).colorScheme.error,
|
||||
),
|
||||
title: Text(
|
||||
context.l10n.channels_deleteChannel,
|
||||
style: const TextStyle(color: Colors.red),
|
||||
style: TextStyle(
|
||||
color: Theme.of(sheetContext).colorScheme.error,
|
||||
),
|
||||
),
|
||||
onTap: () async {
|
||||
Navigator.pop(sheetContext);
|
||||
@@ -723,23 +730,39 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
? (isSelected
|
||||
? Theme.of(dialogContext).colorScheme.primaryContainer
|
||||
: null)
|
||||
: Colors.grey.withValues(alpha: 0.2),
|
||||
: Theme.of(
|
||||
dialogContext,
|
||||
).colorScheme.onSurface.withValues(alpha: 0.12),
|
||||
child: Icon(
|
||||
icon,
|
||||
color: enabled
|
||||
? (isSelected
|
||||
? Theme.of(dialogContext).colorScheme.primary
|
||||
: null)
|
||||
: Colors.grey,
|
||||
: Theme.of(
|
||||
dialogContext,
|
||||
).colorScheme.onSurface.withValues(alpha: 0.38),
|
||||
),
|
||||
),
|
||||
title: Text(
|
||||
title,
|
||||
style: TextStyle(color: enabled ? null : Colors.grey),
|
||||
style: TextStyle(
|
||||
color: enabled
|
||||
? null
|
||||
: Theme.of(
|
||||
dialogContext,
|
||||
).colorScheme.onSurface.withValues(alpha: 0.38),
|
||||
),
|
||||
),
|
||||
subtitle: Text(
|
||||
subtitle,
|
||||
style: TextStyle(color: enabled ? null : Colors.grey),
|
||||
style: TextStyle(
|
||||
color: enabled
|
||||
? null
|
||||
: Theme.of(
|
||||
dialogContext,
|
||||
).colorScheme.onSurface.withValues(alpha: 0.38),
|
||||
),
|
||||
),
|
||||
trailing: enabled ? const Icon(Icons.chevron_right) : null,
|
||||
selected: isSelected,
|
||||
@@ -927,7 +950,11 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
Channel.publicChannelPsk,
|
||||
);
|
||||
Navigator.pop(dialogContext);
|
||||
connector.setChannel(nextIndex, 'Public', psk);
|
||||
connector.setChannel(
|
||||
nextIndex,
|
||||
context.l10n.channels_public,
|
||||
psk,
|
||||
);
|
||||
if (context.mounted) {
|
||||
showDismissibleSnackBar(
|
||||
context,
|
||||
@@ -1041,7 +1068,9 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
dialogContext.l10n.community_hashtagPrivacyHint,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey[600],
|
||||
color: Theme.of(
|
||||
dialogContext,
|
||||
).colorScheme.onSurfaceVariant,
|
||||
fontStyle: FontStyle.italic,
|
||||
),
|
||||
),
|
||||
@@ -1212,6 +1241,8 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
child: FilledButton(
|
||||
onPressed: () async {
|
||||
final name = nameController.text.trim();
|
||||
final publicLabel =
|
||||
context.l10n.channels_public;
|
||||
if (name.isEmpty) {
|
||||
showDismissibleSnackBar(
|
||||
context,
|
||||
@@ -1236,7 +1267,7 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
final psk = community
|
||||
.deriveCommunityPublicPsk();
|
||||
final channelName =
|
||||
'${community.name} Public';
|
||||
'${community.name} $publicLabel';
|
||||
connector.setChannel(
|
||||
nextIndex,
|
||||
channelName,
|
||||
@@ -1592,7 +1623,7 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
},
|
||||
child: Text(
|
||||
dialogContext.l10n.common_delete,
|
||||
style: const TextStyle(color: Colors.red),
|
||||
style: TextStyle(color: Theme.of(context).colorScheme.error),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -1602,7 +1633,7 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
|
||||
void _addPublicChannel(BuildContext context, MeshCoreConnector connector) {
|
||||
final psk = Channel.parsePskHex(Channel.publicChannelPsk);
|
||||
connector.setChannel(0, 'Public', psk);
|
||||
connector.setChannel(0, context.l10n.channels_public, psk);
|
||||
showDismissibleSnackBar(
|
||||
context,
|
||||
content: Text(context.l10n.channels_publicChannelAdded),
|
||||
@@ -1651,14 +1682,19 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
Icon(
|
||||
Icons.groups_outlined,
|
||||
size: 64,
|
||||
color: Colors.grey[400],
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onSurfaceVariant
|
||||
.withValues(alpha: 0.6),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
context.l10n.community_noCommunities,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.grey[600],
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
@@ -1666,7 +1702,10 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
context.l10n.community_scanOrCreate,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.grey[500],
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onSurfaceVariant
|
||||
.withValues(alpha: 0.8),
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
@@ -1690,10 +1729,14 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
),
|
||||
title: Text(community.name),
|
||||
subtitle: Text(
|
||||
'ID: ${community.shortCommunityId}...',
|
||||
context.l10n.channels_communityShortId(
|
||||
community.shortCommunityId,
|
||||
),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey[600],
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
trailing: PopupMenuButton<String>(
|
||||
@@ -1720,14 +1763,20 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
value: 'leave',
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(
|
||||
Icon(
|
||||
Icons.exit_to_app,
|
||||
color: Colors.red,
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.error,
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Text(
|
||||
context.l10n.community_delete,
|
||||
style: const TextStyle(color: Colors.red),
|
||||
style: TextStyle(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.error,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -1828,7 +1877,7 @@ class _ChannelsScreenState extends State<ChannelsScreen>
|
||||
},
|
||||
child: Text(
|
||||
dialogContext.l10n.community_delete,
|
||||
style: const TextStyle(color: Colors.red),
|
||||
style: TextStyle(color: Theme.of(context).colorScheme.error),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user