import 'package:flisp_app/models/flisp.dart'; import 'package:flisp_app/widgets/common.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:toggle_switch/toggle_switch.dart'; Widget buildTabs({ required FlispTab currentTab, required ValueChanged onTabChanged, }) { return Container( padding: EdgeInsets.all(8), child: ToggleSwitch( minWidth: 90.0, minHeight: 40.0, initialLabelIndex: FlispTab.values.indexOf(currentTab), totalSwitches: FlispTab.values.length, labels: FlispTab.values.map((e) => e.label).toList(), activeBgColor: [Colors.orange.shade600], activeFgColor: Colors.white, inactiveBgColor: Colors.grey.shade200, inactiveFgColor: Colors.grey.shade700, cornerRadius: 12.0, customTextStyles: [TextStyle(fontSize: 12, fontWeight: FontWeight.w500)], onToggle: (index) { if (index != null) { onTabChanged(FlispTab.values[index]); } }, ), ); } Widget buildFlispList({ required List flisps, required ValueChanged onEdit, }) { return ListView.separated( itemCount: flisps.length, separatorBuilder: (context, index) => SizedBox(height: 8), itemBuilder: (context, index) { final flisp = flisps[index]; return _buildFlispItem(flisp: flisp, onEdit: onEdit); }, ); } Widget _buildFlispContent(Flisp flisp) { return RichText( text: TextSpan( text: flisp.content, style: const TextStyle( color: Colors.black87, fontWeight: FontWeight.bold, fontSize: 18, ), ), ); } Widget _buildFlispImage(Flisp flisp) { return Container( height: 150, margin: const EdgeInsets.only(bottom: 8), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), image: DecorationImage( image: NetworkImage(flisp.imageUrl), fit: BoxFit.cover, ), ), child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), color: Colors.black.withOpacity(0.3), ), alignment: Alignment.topRight, child: const Padding( padding: EdgeInsets.all(6.0), child: Icon(Icons.image, color: Colors.white, size: 20), ), ), ); } Widget _buildFlispVideo(Flisp flisp) { return Container( height: 120, margin: const EdgeInsets.only(bottom: 8), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), color: Colors.grey[300], ), child: Stack( alignment: Alignment.center, children: [ // 视频缩略图背景 Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), color: Colors.blue[100], gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [Colors.blue[200]!, Colors.blue[400]!], ), ), ), // 播放按钮 const CircleAvatar( backgroundColor: Colors.white, radius: 24, child: Icon(Icons.play_arrow, color: Colors.red, size: 36), ), // 视频标识 const Positioned( top: 8, right: 8, child: Icon(Icons.videocam, color: Colors.red, size: 20), ), // 视频时长 const Positioned( bottom: 8, right: 8, child: Text( '02:30', style: TextStyle( color: Colors.white, fontSize: 12, fontWeight: FontWeight.bold, ), ), ), ], ), ); } Widget _buildFlispTag(Flisp flisp) { return Row( children: [ // 只有一个标签,直接显示 Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), decoration: BoxDecoration( color: Colors.orange, borderRadius: BorderRadius.circular(12), ), child: Text( flisp.tag.label, style: const TextStyle(fontSize: 12, color: Colors.white), ), ), const Spacer(), // 时间在后 Text( DateFormat('yyyy-MM-dd HH:mm').format(flisp.createTime), style: TextStyle(fontSize: 12, color: Colors.grey[500]), ), ], ); } Widget _buildFlispItem({ required Flisp flisp, required ValueChanged onEdit, }) { final hasImage = flisp.imageUrl.isNotEmpty; final hasVideo = flisp.videoUrl.isNotEmpty; return buildCard( child: InkWell( onTap: () => onEdit(flisp), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildFlispContent(flisp), const SizedBox(height: 8), if (hasImage) _buildFlispImage(flisp), const SizedBox(height: 4), if (hasVideo) _buildFlispVideo(flisp), const SizedBox(height: 4), _buildFlispTag(flisp), ], ), ), ); } // 空状态 Widget buildEmptyState() { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.checklist, size: 80, color: Colors.orange.shade600), Text( '📝 还没有闪灵\n点击➕号添加第一个任务吧~', textAlign: TextAlign.center, style: TextStyle(color: Colors.orange.shade600), ), ], ), ); }