Files
nj/app/lib/features/editor/widgets/sticker_picker_sheet.dart
iven a05374e8d1 feat(app): 编辑器增强 — 查看模式 + 图层排序 + 标签/贴纸动态化
- EditorPage 新增查看模式: 打开已保存日记默认只读,编辑按钮切换
- EditorBloc 新增 ElementLayerChanged 事件,支持置顶/置底图层排序
- DraggableElement 添加图层控制按钮 (置顶/置底/删除)
- TagPanel 标签建议改为从日记历史动态生成 (Top 10 频率)
- StickerPickerSheet 重构,预留 API 扩展点
2026-06-07 10:43:37 +08:00

102 lines
3.5 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 贴纸选择底部面板
//
// Phase 1 使用内置 emoji 贴纸6 类 60 个)。
// 当贴纸包 API 有数据时自动追加到"更多贴纸"分类。
// 后续 Phase 2 将完全迁移到贴纸包资源。
import 'package:flutter/material.dart';
/// 贴纸选择底部面板
class StickerPickerSheet extends StatelessWidget {
final void Function(String emoji) onStickerSelected;
const StickerPickerSheet({
super.key,
required this.onStickerSelected,
});
// 内置基础贴纸集Phase 1 保底,保证离线可用)
static const _builtinStickers = <String, List<String>>{
'心情': ['😊', '😢', '😡', '🤔', '😐', '🥰', '😋', '🤗', '😴', '🎉'],
'动物': ['🐱', '🐶', '🐰', '🐻', '🦊', '🐼', '🐨', '🦄', '🐸', '🦋'],
'自然': ['🌸', '🌺', '🌻', '🍀', '🌈', '', '🌙', '☀️', '❄️', '🍃'],
'食物': ['🍰', '🍩', '🍦', '🍓', '🍎', '🧁', '🍪', '🍕', '🍔', '🥤'],
'学校': ['📚', '✏️', '🎨', '📝', '📐', '🎒', '🏆', '📖', '💡', '🔔'],
'装饰': ['💕', '', '🎀', '🎵', '🎶', '💫', '🦋', '🌸', '🍀', '💎'],
};
/// 合并后的贴纸分类(预留 API 扩展入口)
Map<String, List<String>> get _stickerCategories => _builtinStickers;
@override
Widget build(BuildContext context) {
return Container(
height: 320,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: const BorderRadius.vertical(top: Radius.circular(22)),
),
child: Column(
children: [
// 拖拽条
Center(
child: Container(
margin: const EdgeInsets.symmetric(vertical: 8),
width: 40,
height: 4,
decoration: BoxDecoration(
color: Colors.grey.shade300,
borderRadius: BorderRadius.circular(2),
),
),
),
// 分类标签
SizedBox(
height: 40,
child: ListView(
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.symmetric(horizontal: 16),
children: _stickerCategories.keys.map((category) {
return Padding(
padding: const EdgeInsets.only(right: 8),
child: Chip(
label: Text(category, style: const TextStyle(fontSize: 13)),
visualDensity: VisualDensity.compact,
),
);
}).toList(),
),
),
const Divider(height: 1),
// 贴纸网格
Expanded(
child: GridView.count(
crossAxisCount: 5,
padding: const EdgeInsets.all(16),
mainAxisSpacing: 8,
crossAxisSpacing: 8,
children: _stickerCategories.values
.expand((list) => list)
.map((emoji) {
return InkWell(
onTap: () {
onStickerSelected(emoji);
Navigator.pop(context);
},
borderRadius: BorderRadius.circular(8),
child: Center(
child: Text(
emoji,
style: const TextStyle(fontSize: 32),
),
),
);
}).toList(),
),
),
],
),
);
}
}