595 lines
19 KiB
Dart
595 lines
19 KiB
Dart
// import 'package:flutter/material.dart';
|
|
// import 'package:flutter/services.dart';
|
|
// import '../models/channel.dart';
|
|
// import '../services/api_service.dart';
|
|
// import '../services/auth_service.dart';
|
|
// import 'channel_screen.dart';
|
|
// import 'login_screen.dart';
|
|
// import 'notifications_screen.dart';
|
|
// import 'wifi_screen.dart';
|
|
|
|
// class ChannelListScreen extends StatefulWidget {
|
|
// const ChannelListScreen({super.key});
|
|
|
|
// @override
|
|
// State<ChannelListScreen> createState() => _ChannelListScreenState();
|
|
// }
|
|
|
|
// class _ChannelListScreenState extends State<ChannelListScreen> {
|
|
// static final _nativeChannel = const MethodChannel(
|
|
// 'com.example.watch/launcher',
|
|
// );
|
|
|
|
// final _authService = AuthService();
|
|
// late final ApiService _api;
|
|
|
|
// List<Channel> _channels = [];
|
|
// bool _loading = true;
|
|
// int _pendingNotifCount = 0;
|
|
// String? _currentUserId;
|
|
// PageController? _pageCtrl;
|
|
// int _currentPage = 0;
|
|
// bool _initialized = false;
|
|
|
|
// // Battery
|
|
// int _batteryLevel = 0;
|
|
// bool _isCharging = false;
|
|
|
|
// @override
|
|
// void initState() {
|
|
// super.initState();
|
|
// _api = ApiService(_authService);
|
|
// _init();
|
|
// }
|
|
|
|
// Future<void> _init() async {
|
|
// _currentUserId = await _authService.getUserId();
|
|
// await Future.wait([_loadChannels(), _loadNotifCount(), _loadBattery()]);
|
|
// }
|
|
|
|
// Future<void> _loadBattery() async {
|
|
// try {
|
|
// final info = await _nativeChannel.invokeMapMethod<String, dynamic>(
|
|
// 'getBatteryInfo',
|
|
// );
|
|
// if (!mounted || info == null) return;
|
|
// setState(() {
|
|
// _batteryLevel = (info['level'] as int?) ?? 0;
|
|
// _isCharging = (info['isCharging'] as bool?) ?? false;
|
|
// });
|
|
// } catch (_) {}
|
|
// }
|
|
|
|
// Future<void> _loadChannels() async {
|
|
// setState(() => _loading = true);
|
|
// final channels = await _api.getChannels();
|
|
// if (!mounted) return;
|
|
// setState(() {
|
|
// _channels = channels;
|
|
// _loading = false;
|
|
// if (!_initialized) {
|
|
// final startPage = channels.isNotEmpty ? 1 : 0;
|
|
// _pageCtrl = PageController(initialPage: startPage);
|
|
// _currentPage = startPage;
|
|
// _initialized = true;
|
|
// }
|
|
// });
|
|
// }
|
|
|
|
// Future<void> _loadNotifCount() async {
|
|
// final notifs = await _api.getNotifications();
|
|
// if (!mounted) return;
|
|
// setState(() {
|
|
// _pendingNotifCount = notifs.where((n) => n.isPending).length;
|
|
// });
|
|
// }
|
|
|
|
// Future<void> _refresh() async {
|
|
// await _loadChannels();
|
|
// await _loadNotifCount();
|
|
// }
|
|
|
|
// Future<void> _openInternetSettings() async {
|
|
// try {
|
|
// await _nativeChannel.invokeMethod('openInternetSettings');
|
|
// } catch (_) {
|
|
// if (!mounted) return;
|
|
// _showSnack('تنظیمات اینترنت در دسترس نیست');
|
|
// }
|
|
// }
|
|
|
|
// void _openWifi() {
|
|
// Navigator.push(
|
|
// context,
|
|
// MaterialPageRoute(builder: (_) => const WifiScreen()),
|
|
// );
|
|
// }
|
|
|
|
// Future<void> _openAccessibilitySettings() async {
|
|
// try {
|
|
// await _nativeChannel.invokeMethod('openAccessibilitySettings');
|
|
// } catch (e) {
|
|
// _showSnack('خطا در باز کردن تنظیمات');
|
|
// }
|
|
// }
|
|
|
|
// void _showSnack(String msg) {
|
|
// ScaffoldMessenger.of(context).showSnackBar(
|
|
// SnackBar(
|
|
// content: Text(
|
|
// msg,
|
|
// style: const TextStyle(fontSize: 10, color: Colors.white),
|
|
// textAlign: TextAlign.center,
|
|
// ),
|
|
// backgroundColor: const Color(0xFF2C2C2E),
|
|
// behavior: SnackBarBehavior.floating,
|
|
// duration: const Duration(seconds: 2),
|
|
// margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 40),
|
|
// ),
|
|
// );
|
|
// }
|
|
|
|
// Future<void> _openHomeSettings() async {
|
|
// try {
|
|
// await _nativeChannel.invokeMethod('openHomeSettings');
|
|
// } catch (_) {
|
|
// if (!mounted) return;
|
|
// ScaffoldMessenger.of(context).showSnackBar(
|
|
// const SnackBar(
|
|
// content: Text(
|
|
// 'این قابلیت روی دستگاه شما پشتیبانی نمیشود',
|
|
// style: TextStyle(fontSize: 10, color: Colors.white),
|
|
// textAlign: TextAlign.center,
|
|
// ),
|
|
// backgroundColor: Color(0xFF2C2C2E),
|
|
// behavior: SnackBarBehavior.floating,
|
|
// duration: Duration(seconds: 2),
|
|
// margin: EdgeInsets.symmetric(horizontal: 16, vertical: 40),
|
|
// ),
|
|
// );
|
|
// }
|
|
// }
|
|
|
|
// Future<void> _logout() async {
|
|
// await _authService.logout();
|
|
// if (!mounted) return;
|
|
// Navigator.pushReplacement(
|
|
// context,
|
|
// MaterialPageRoute(builder: (_) => const LoginScreen()),
|
|
// );
|
|
// }
|
|
|
|
// void _enterChannel(Channel ch) {
|
|
// Navigator.push(
|
|
// context,
|
|
// MaterialPageRoute(
|
|
// builder: (_) =>
|
|
// ChannelScreen(channel: ch, currentUserId: _currentUserId),
|
|
// ),
|
|
// );
|
|
// }
|
|
|
|
// void _openNotifications() async {
|
|
// await Navigator.push(
|
|
// context,
|
|
// MaterialPageRoute(builder: (_) => const NotificationsScreen()),
|
|
// );
|
|
// _refresh();
|
|
// }
|
|
|
|
// Future<void> _showCreateGroupDialog() async {
|
|
// String groupName = '';
|
|
// final confirmed = await showDialog<bool>(
|
|
// context: context,
|
|
// builder: (ctx) => _CreateGroupDialog(onNameChanged: (v) => groupName = v),
|
|
// );
|
|
// if (confirmed == true && groupName.trim().isNotEmpty) {
|
|
// final newChannel = await _api.createGroup(groupName.trim());
|
|
// if (!mounted) return;
|
|
// ScaffoldMessenger.of(context).showSnackBar(
|
|
// SnackBar(
|
|
// content: Text(
|
|
// newChannel != null ? 'گروه ساخته شد' : 'خطا در ساخت گروه',
|
|
// style: const TextStyle(fontSize: 11, color: Colors.white),
|
|
// textAlign: TextAlign.center,
|
|
// ),
|
|
// backgroundColor: const Color(0xFF2C2C2E),
|
|
// behavior: SnackBarBehavior.floating,
|
|
// duration: const Duration(seconds: 2),
|
|
// margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 40),
|
|
// shape: RoundedRectangleBorder(
|
|
// borderRadius: BorderRadius.circular(20),
|
|
// ),
|
|
// ),
|
|
// );
|
|
// if (newChannel != null) _loadChannels();
|
|
// }
|
|
// }
|
|
|
|
// @override
|
|
// void dispose() {
|
|
// _pageCtrl?.dispose();
|
|
// super.dispose();
|
|
// }
|
|
|
|
// @override
|
|
// Widget build(BuildContext context) {
|
|
// if (_loading || _pageCtrl == null) {
|
|
// return const Scaffold(
|
|
// backgroundColor: Colors.black,
|
|
// body: Center(
|
|
// child: CircularProgressIndicator(
|
|
// color: Color(0xFF00C853),
|
|
// strokeWidth: 2,
|
|
// ),
|
|
// ),
|
|
// );
|
|
// }
|
|
|
|
// final totalPages = _channels.length + 1; // +1 for menu page
|
|
|
|
// return Scaffold(
|
|
// backgroundColor: Colors.black,
|
|
// body: SafeArea(
|
|
// child: Column(
|
|
// children: [
|
|
// Expanded(
|
|
// child: PageView.builder(
|
|
// controller: _pageCtrl!,
|
|
// scrollDirection: Axis.vertical,
|
|
// onPageChanged: (i) => setState(() => _currentPage = i),
|
|
// itemCount: totalPages,
|
|
// itemBuilder: (ctx, i) {
|
|
// if (i == 0) return _buildMenuPage();
|
|
// return _buildChannelPage(_channels[i - 1]);
|
|
// },
|
|
// ),
|
|
// ),
|
|
// _buildPageIndicator(totalPages),
|
|
// ],
|
|
// ),
|
|
// ),
|
|
// );
|
|
// }
|
|
|
|
// Widget _buildPageIndicator(int totalPages) {
|
|
// return Padding(
|
|
// padding: const EdgeInsets.only(bottom: 6, top: 2),
|
|
// child: Row(
|
|
// mainAxisAlignment: MainAxisAlignment.center,
|
|
// children: List.generate(totalPages, (i) {
|
|
// final isActive = i == _currentPage;
|
|
// if (i == 0) {
|
|
// return Padding(
|
|
// padding: const EdgeInsets.symmetric(horizontal: 2),
|
|
// child: Icon(
|
|
// Icons.menu,
|
|
// size: isActive ? 9 : 6,
|
|
// color: isActive ? Colors.white70 : Colors.white24,
|
|
// ),
|
|
// );
|
|
// }
|
|
// return Padding(
|
|
// padding: const EdgeInsets.symmetric(horizontal: 2),
|
|
// child: Container(
|
|
// width: isActive ? 6 : 4,
|
|
// height: isActive ? 6 : 4,
|
|
// decoration: BoxDecoration(
|
|
// color: isActive ? const Color(0xFF00C853) : Colors.white24,
|
|
// shape: BoxShape.circle,
|
|
// ),
|
|
// ),
|
|
// );
|
|
// }),
|
|
// ),
|
|
// );
|
|
// }
|
|
|
|
// Widget _buildMenuPage() {
|
|
// final batteryColor = _isCharging
|
|
// ? const Color(0xFF00C853)
|
|
// : _batteryLevel <= 15
|
|
// ? const Color(0xFFFF1744)
|
|
// : _batteryLevel <= 30
|
|
// ? const Color(0xFFFFAB00)
|
|
// : Colors.white60;
|
|
|
|
// // تغییر ListView به SingleChildScrollView و Column
|
|
// return Column(
|
|
// mainAxisSize: MainAxisSize.min, // ستون فقط به اندازه محتوا فضا میگیرد
|
|
// children: [
|
|
// // _// Battery display_
|
|
// Container(
|
|
// height: 32,
|
|
// margin: const EdgeInsets.only(bottom: 6),
|
|
// padding: const EdgeInsets.symmetric(horizontal: 12),
|
|
// decoration: BoxDecoration(
|
|
// color: batteryColor.withValues(alpha: 0.1),
|
|
// borderRadius: BorderRadius.circular(12),
|
|
// border: Border.all(
|
|
// color: batteryColor.withValues(alpha: 0.3),
|
|
// width: 1,
|
|
// ),
|
|
// ),
|
|
// child: Row(
|
|
// children: [
|
|
// Icon(
|
|
// _isCharging ? Icons.bolt : Icons.battery_std,
|
|
// color: batteryColor,
|
|
// size: 14,
|
|
// ),
|
|
// const SizedBox(width: 6),
|
|
// Text(
|
|
// _isCharging
|
|
// ? 'در حال شارژ — $_batteryLevel%'
|
|
// : 'باتری: $_batteryLevel%',
|
|
// style: TextStyle(color: batteryColor, fontSize: 10),
|
|
// ),
|
|
// ],
|
|
// ),
|
|
// ),
|
|
// const SizedBox(height: 6),
|
|
// _MenuItem(
|
|
// icon: Icons.notifications_outlined,
|
|
// label: _pendingNotifCount > 0
|
|
// ? 'اعلانها ($_pendingNotifCount)'
|
|
// : 'اعلانها',
|
|
// color: _pendingNotifCount > 0
|
|
// ? const Color(0xFFFF1744)
|
|
// : Colors.white70,
|
|
// onTap: _openNotifications,
|
|
// ),
|
|
// const SizedBox(height: 6),
|
|
// _MenuItem(
|
|
// icon: Icons.wifi,
|
|
// label: 'وایفای',
|
|
// color: const Color(0xFF2979FF),
|
|
// onTap: _openWifi,
|
|
// ),
|
|
// const SizedBox(height: 6),
|
|
// _MenuItem(
|
|
// icon: Icons.cell_tower,
|
|
// label: 'اینترنت / سیمکارت',
|
|
// color: const Color(0xFF00BCD4),
|
|
// onTap: _openInternetSettings,
|
|
// ),
|
|
// const SizedBox(height: 6),
|
|
// _MenuItem(
|
|
// icon: Icons.accessibility_new,
|
|
// label: 'تنظیمات دکمهها',
|
|
// color: Colors.orangeAccent,
|
|
// onTap: _openAccessibilitySettings,
|
|
// ),
|
|
// const SizedBox(height: 6),
|
|
// _MenuItem(
|
|
// icon: Icons.add_circle_outline,
|
|
// label: 'گروه جدید',
|
|
// color: const Color(0xFF00C853),
|
|
// onTap: _showCreateGroupDialog,
|
|
// ),
|
|
// const SizedBox(height: 6),
|
|
// _MenuItem(
|
|
// icon: Icons.refresh,
|
|
// label: 'بروزرسانی',
|
|
// color: Colors.white70,
|
|
// onTap: _loading ? null : _refresh,
|
|
// ),
|
|
// const SizedBox(height: 6),
|
|
// _MenuItem(
|
|
// icon: Icons.launch,
|
|
// label: 'تغییر لانچر',
|
|
// color: Colors.white54,
|
|
// onTap: _openHomeSettings,
|
|
// ),
|
|
// const SizedBox(height: 6),
|
|
// _MenuItem(
|
|
// icon: Icons.logout,
|
|
// label: 'خروج',
|
|
// color: Colors.redAccent,
|
|
// onTap: _logout,
|
|
// ),
|
|
// ],
|
|
// );
|
|
// }
|
|
|
|
// Widget _buildChannelPage(Channel channel) {
|
|
// return Center(
|
|
// child: GestureDetector(
|
|
// onTap: () => _enterChannel(channel),
|
|
// child: LayoutBuilder(
|
|
// builder: (ctx, constraints) {
|
|
// final size = constraints.maxWidth * 0.72;
|
|
// return Container(
|
|
// width: size,
|
|
// height: size,
|
|
// decoration: BoxDecoration(
|
|
// color: const Color(0xFF1C1C1E),
|
|
// shape: BoxShape.circle,
|
|
// border: Border.all(
|
|
// color: const Color(0xFF00C853).withValues(alpha: 0.55),
|
|
// width: 2,
|
|
// ),
|
|
// boxShadow: [
|
|
// BoxShadow(
|
|
// color: const Color(0xFF00C853).withValues(alpha: 0.12),
|
|
// blurRadius: 22,
|
|
// spreadRadius: 2,
|
|
// ),
|
|
// ],
|
|
// ),
|
|
// child: Column(
|
|
// mainAxisAlignment: MainAxisAlignment.center,
|
|
// children: [
|
|
// Icon(
|
|
// channel.type == 'PUBLIC' ? Icons.radio : Icons.lock_outline,
|
|
// color: const Color(0xFF00C853),
|
|
// size: 22,
|
|
// ),
|
|
// const SizedBox(height: 8),
|
|
// Padding(
|
|
// padding: const EdgeInsets.symmetric(horizontal: 20),
|
|
// child: Text(
|
|
// channel.name,
|
|
// style: const TextStyle(
|
|
// color: Colors.white,
|
|
// fontSize: 13,
|
|
// fontWeight: FontWeight.bold,
|
|
// ),
|
|
// textAlign: TextAlign.center,
|
|
// maxLines: 2,
|
|
// overflow: TextOverflow.ellipsis,
|
|
// ),
|
|
// ),
|
|
// const SizedBox(height: 4),
|
|
// Text(
|
|
// channel.type == 'PUBLIC' ? 'عمومی' : 'خصوصی',
|
|
// style: const TextStyle(color: Colors.white38, fontSize: 9),
|
|
// ),
|
|
// ],
|
|
// ),
|
|
// );
|
|
// },
|
|
// ),
|
|
// ),
|
|
// );
|
|
// }
|
|
// }
|
|
|
|
// // ── Menu Item ──────────────────────────────────────────────────────────────
|
|
|
|
// class _MenuItem extends StatelessWidget {
|
|
// final IconData icon;
|
|
// final String label;
|
|
// final Color color;
|
|
// final VoidCallback? onTap;
|
|
|
|
// const _MenuItem({
|
|
// required this.icon,
|
|
// required this.label,
|
|
// required this.color,
|
|
// this.onTap,
|
|
// });
|
|
|
|
// @override
|
|
// Widget build(BuildContext context) {
|
|
// return GestureDetector(
|
|
// onTap: onTap,
|
|
// child: Container(
|
|
// height: 38,
|
|
// padding: const EdgeInsets.symmetric(horizontal: 12),
|
|
// decoration: BoxDecoration(
|
|
// color: const Color(0xFF1C1C1E),
|
|
// borderRadius: BorderRadius.circular(12),
|
|
// ),
|
|
// child: Row(
|
|
// children: [
|
|
// Icon(icon, color: color, size: 16),
|
|
// const SizedBox(width: 8),
|
|
// Expanded(
|
|
// child: Text(label, style: TextStyle(color: color, fontSize: 11)),
|
|
// ),
|
|
// ],
|
|
// ),
|
|
// ),
|
|
// );
|
|
// }
|
|
// }
|
|
|
|
// // ── Create Group Dialog ────────────────────────────────────────────────────
|
|
|
|
// class _CreateGroupDialog extends StatefulWidget {
|
|
// final ValueChanged<String> onNameChanged;
|
|
|
|
// const _CreateGroupDialog({required this.onNameChanged});
|
|
|
|
// @override
|
|
// State<_CreateGroupDialog> createState() => _CreateGroupDialogState();
|
|
// }
|
|
|
|
// class _CreateGroupDialogState extends State<_CreateGroupDialog> {
|
|
// final _ctrl = TextEditingController();
|
|
|
|
// @override
|
|
// void dispose() {
|
|
// _ctrl.dispose();
|
|
// super.dispose();
|
|
// }
|
|
|
|
// @override
|
|
// Widget build(BuildContext context) {
|
|
// return AlertDialog(
|
|
// backgroundColor: const Color(0xFF1C1C1E),
|
|
// shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
|
// contentPadding: const EdgeInsets.all(16),
|
|
// content: Column(
|
|
// mainAxisSize: MainAxisSize.min,
|
|
// children: [
|
|
// const Icon(
|
|
// Icons.add_circle_outline,
|
|
// color: Color(0xFF00C853),
|
|
// size: 26,
|
|
// ),
|
|
// const SizedBox(height: 8),
|
|
// const Text(
|
|
// 'گروه جدید',
|
|
// style: TextStyle(
|
|
// color: Colors.white,
|
|
// fontSize: 12,
|
|
// fontWeight: FontWeight.bold,
|
|
// ),
|
|
// ),
|
|
// const SizedBox(height: 10),
|
|
// TextField(
|
|
// controller: _ctrl,
|
|
// autofocus: true,
|
|
// textAlign: TextAlign.center,
|
|
// style: const TextStyle(color: Colors.white, fontSize: 12),
|
|
// decoration: InputDecoration(
|
|
// hintText: 'نام گروه',
|
|
// hintStyle: const TextStyle(color: Colors.white38, fontSize: 11),
|
|
// filled: true,
|
|
// fillColor: Colors.white.withValues(alpha: 0.05),
|
|
// border: OutlineInputBorder(
|
|
// borderRadius: BorderRadius.circular(10),
|
|
// borderSide: BorderSide.none,
|
|
// ),
|
|
// contentPadding: const EdgeInsets.symmetric(
|
|
// horizontal: 12,
|
|
// vertical: 8,
|
|
// ),
|
|
// ),
|
|
// onChanged: widget.onNameChanged,
|
|
// ),
|
|
// const SizedBox(height: 12),
|
|
// Row(
|
|
// children: [
|
|
// Expanded(
|
|
// child: TextButton(
|
|
// onPressed: () => Navigator.pop(context, false),
|
|
// child: const Text(
|
|
// 'انصراف',
|
|
// style: TextStyle(color: Colors.white54, fontSize: 11),
|
|
// ),
|
|
// ),
|
|
// ),
|
|
// Expanded(
|
|
// child: TextButton(
|
|
// onPressed: () => Navigator.pop(context, true),
|
|
// child: const Text(
|
|
// 'ساخت',
|
|
// style: TextStyle(
|
|
// color: Color(0xFF00C853),
|
|
// fontSize: 11,
|
|
// fontWeight: FontWeight.bold,
|
|
// ),
|
|
// ),
|
|
// ),
|
|
// ),
|
|
// ],
|
|
// ),
|
|
// ],
|
|
// ),
|
|
// );
|
|
// }
|
|
// }
|