Skip to content

小组件#61

Merged
ZHLX2005 merged 1228 commits into
ZHLX2005:masterfrom
joke-lx:master
Jun 4, 2026
Merged

小组件#61
ZHLX2005 merged 1228 commits into
ZHLX2005:masterfrom
joke-lx:master

Conversation

@joke-lx

@joke-lx joke-lx commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

No description provided.

joke-lx and others added 30 commits May 14, 2026 14:12
* 拖拽

* 拖拽

* 拖拽

* 拖拽

* 拖拽

* 拖拽

* 拖拽

* line demo

* 拖拽

* perf(chat): 优化FormatCompatibilityPage减少键盘弹出时的卡顿

- 使用SchedulerBinding.addPostFrameCallback替代Future.delayed滚动
- 缓存factory引用避免重复GetIt查找
- 使用MediaQuery.sizeOf替代MediaQuery.of避免监听变化
- 添加RepaintBoundary隔离消息气泡重绘
- 修复withOpacity已废弃警告

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* perf(chat): 完全解耦输入区和消息列表防止键盘触发重建

将_MessageList和_InputArea提取为独立StatelessWidget,
彻底隔离键盘弹出时对消息列表的影响

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 栈

* 栈

* 按照skill严格校验

* 按照skill严格校验

---------

Co-authored-by: zhaoliuxue <2096343460@qq.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
# Conflicts:
#	android/app/src/main/kotlin/io/github/xiaodouzi/fr/native/pigment/PigmentFloatingManager.kt
* 拖拽

* 拖拽

* 拖拽

* 拖拽

* 拖拽

* 拖拽

* 拖拽

* line demo

* 拖拽

* perf(chat): 优化FormatCompatibilityPage减少键盘弹出时的卡顿

- 使用SchedulerBinding.addPostFrameCallback替代Future.delayed滚动
- 缓存factory引用避免重复GetIt查找
- 使用MediaQuery.sizeOf替代MediaQuery.of避免监听变化
- 添加RepaintBoundary隔离消息气泡重绘
- 修复withOpacity已废弃警告

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* perf(chat): 完全解耦输入区和消息列表防止键盘触发重建

将_MessageList和_InputArea提取为独立StatelessWidget,
彻底隔离键盘弹出时对消息列表的影响

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 栈

* 栈

* 按照skill严格校验

* 按照skill严格校验

* 按照skill严格校验

* 按照skill严格校验

---------

Co-authored-by: zhaoliuxue <2096343460@qq.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
- 新增圆形色相环调色板,支持自定义屏幕光颜色
- 添加10种护眼预设颜色(护眼黄、琥珀、暖白等)
- 全屏模式3秒无操作自动隐藏控制UI,点击恢复
- 提取常量到 const_torch.dart 统一管理

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
- APK更新从第3个Tab移至第1个Tab,作为默认页面
- 新增 ApkDownloadManager 全局单例,管理下载状态
- 下载状态通过 ValueNotifier 广播,页面间共享
- 离开API测试页面后下载继续,返回可查看实时进度
- 下载结果持久化到 SharedPreferences,重启后保留

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
- 删除 my_diary_header_demo.dart 独立页面
- 提取日记头部的压缩圆角头部效果,迁移至 grid_dashboard_demo.dart
- 使用 CustomScrollView + SliverPersistentHeader(pinned: false) 实现折叠式圆角渐变头部
- 头部随滚动压缩,圆角从40px渐变到0,标题缩小
- 白色内容区顶部保持32px圆角覆盖在渐变头部下方
- 从 lab_bootstrap.dart 注销日记头部demo注册

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
- 新增 api_speech_tab.dart:提取自 speech_synthesis_demo.dart,移除 DemoPage 继承
- 修改 api_test_demo.dart:TabController length 3→4,新增"语音合成" tab
- 删除独立的 speech_synthesis_demo.dart
- 更新 lab_bootstrap.dart:移除语音合成 demo 的注册

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
将单文件 demo 的辅助文件按规范移至子目录:
- const_torch.dart → torch/const_torch.dart
- api_download_manager.dart → api_test/api_download_manager.dart
- api_speech_tab.dart → api_test/api_speech_tab.dart

同步更新 torch_demo.dart 和 api_test_demo.dart 的 import 路径。

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
文件位于 lib/lab/demos/api_test/,需向上三级到 lib/ 才能进入 services/,
原导入仅向上两级导致 ApiService / DownloadController 未定义、analyze 报 5 个 error。

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Factory.rive 在 Dialog 中使用 TextureLayer 合成,
Dialog 入场动画重建层树时 TextureLayer 被逐出且无 markNeedsPaint 恢复,
导致播放过程中丢帧。改用 Factory.flutter 使用 Flutter Canvas 渲染,
每帧主动标记重绘,避免此问题。
页面跳转和 Tab 切换卡顿同根因:Factory.rive 的 TextureLayer
在 route/AnimatedSwitcher 层树重建时被冲掉。
改用 Factory.flutter 使用 Canvas 绘制,每帧主动标记重绘解决。
- 移除 _BookmarkTab / _BookmarkTabClipper / _BookmarkSide(约180行)
- 新增 _ProfileDot 8×8 圆点指示器,激活态实心/非激活态空心边框
- 用 PageView 替换 AnimatedSwitcher,支持左右滑动切换
- 圆点叠加在内容区左上角,不遮挡内容
用 Column 布局替代 Stack 叠加,圆点 Row 在内容区顶部,
PageView 通过 Expanded 填充剩余空间,圆点不再遮挡卡片圆角。
- DownloadController:新增 isPaused 与 pause() 方法,与 cancel 语义分离
  - cancel: 终止并删除临时文件
  - pause:  终止但保留临时文件,下次基于 HTTP Range 续传
- ApiService.downloadApkToLocal:暂停路径不再删除 tempFile;新增 getApkTempFileInfo/clearApkTempFile 工具方法
- ApkDownloadManager:
  - 新状态字段 isPaused / receivedBytes / totalBytes,进度持久化到 SharedPreferences
  - 新方法 pauseDownload / resumeDownload,cancelDownload 兼容暂停态清理
  - loadSavedState 检测临时文件,启动时恢复暂停态
- UI:三态主操作按钮(内部下载 / 暂停 / 继续)+ 独立取消按钮;进度条在下载中与暂停时均可见,显示已下载/总大小

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
- 抽离到 lab/demos/network/ 子目录(方案 a)
  - const_network.dart 常量统一管理
  - network_widgets.dart 公共组件(可复制信息行、状态徽标、信号图标)
  - network_env_tab.dart 网络环境(增强:公网IP/DNS解析延迟/HTTP连通性测试/平台信息)
  - network_http_tab.dart HTTP 请求测试
  - network_ws_tab.dart WebSocket 测试
  - network_ble_tab.dart 蓝牙 BLE 测试
- 删除 network_env_demo.dart
- 进入即看环境信息,方便快速 debug

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
问题:
- 冷启动时 LabClockProvider 不主动 loadClocks,要等用户进入 clock 页面才加载,
  期间桌面小组件读到的是上次保存的旧数据
- _recalculateRunningClocks 重算后没调 _syncToWidget,resume 后 widget 仍停留在旧值
- 原生侧只读 clock_formatted_time 这个被冻结的字符串,Flutter 进程死掉后
  widget 下次刷新依然是过期时间
- ClockWidgetService 静默吞掉 home_widget 异常,问题无法定位

修复:
- LabClockProvider 构造里直接 loadClocks,并在 loadClocks/resume 结尾调 _syncToWidget
- ClockWidgetData 新增 startTimeMs / startRemainingSeconds 透传到原生
- ClockWidgetProvider.kt 基于 startTimeMs 实时计算 remaining/isOvertime/formatted,
  即使 Flutter 进程被杀,下次 widget 刷新仍能显示准确时间
- 把静默 catch 改成 debugPrint,便于后续排查
* 拖拽

* 拖拽

* 拖拽

* 拖拽

* 拖拽

* 拖拽

* 拖拽

* line demo

* 拖拽

* perf(chat): 优化FormatCompatibilityPage减少键盘弹出时的卡顿

- 使用SchedulerBinding.addPostFrameCallback替代Future.delayed滚动
- 缓存factory引用避免重复GetIt查找
- 使用MediaQuery.sizeOf替代MediaQuery.of避免监听变化
- 添加RepaintBoundary隔离消息气泡重绘
- 修复withOpacity已废弃警告

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* perf(chat): 完全解耦输入区和消息列表防止键盘触发重建

将_MessageList和_InputArea提取为独立StatelessWidget,
彻底隔离键盘弹出时对消息列表的影响

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 栈

* 栈

* 按照skill严格校验

* 按照skill严格校验

* 按照skill严格校验

* 按照skill严格校验

* fix: 底部导航 Rive 动画卡顿 - 改用 Factory.flutter 渲染

Factory.rive 在 Dialog 中使用 TextureLayer 合成,
Dialog 入场动画重建层树时 TextureLayer 被逐出且无 markNeedsPaint 恢复,
导致播放过程中丢帧。改用 Factory.flutter 使用 Flutter Canvas 渲染,
每帧主动标记重绘,避免此问题。

* fix: 人物小谱页面 Rive 卡顿 - 改用 Factory.flutter 渲染

页面跳转和 Tab 切换卡顿同根因:Factory.rive 的 TextureLayer
在 route/AnimatedSwitcher 层树重建时被冲掉。
改用 Factory.flutter 使用 Canvas 绘制,每帧主动标记重绘解决。

* refactor: 书签标签改为圆点指示器 + PageView 滑动切换

- 移除 _BookmarkTab / _BookmarkTabClipper / _BookmarkSide(约180行)
- 新增 _ProfileDot 8×8 圆点指示器,激活态实心/非激活态空心边框
- 用 PageView 替换 AnimatedSwitcher,支持左右滑动切换
- 圆点叠加在内容区左上角,不遮挡内容

* fix: 圆点移到圆框上方,AppBar 下方顶层

用 Column 布局替代 Stack 叠加,圆点 Row 在内容区顶部,
PageView 通过 Expanded 填充剩余空间,圆点不再遮挡卡片圆角。

* notion

* notion

---------

Co-authored-by: zhaoliuxue <2096343460@qq.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
joke-lx and others added 28 commits June 3, 2026 19:23
- 添加 READ_CALENDAR/WRITE_CALENDAR 权限
- 新增 CalendarChannel.kt 原生桥接(插入/删除系统日历事件)
- 新增 CalendarService.dart Flutter 端 MethodChannel
- LabCalendarEvent 增加 systemCalendarEventId 字段
- Provider 增加 syncToSystemCalendar 方法
- 事件抽屉增加同步按钮和已同步标记
- 桌面小组件 deep link 改为 fr://calendar 直接打开日历页
* 拖拽

* 拖拽

* 拖拽

* 拖拽

* 拖拽

* 拖拽

* 拖拽

* line demo

* 拖拽

* perf(chat): 优化FormatCompatibilityPage减少键盘弹出时的卡顿

- 使用SchedulerBinding.addPostFrameCallback替代Future.delayed滚动
- 缓存factory引用避免重复GetIt查找
- 使用MediaQuery.sizeOf替代MediaQuery.of避免监听变化
- 添加RepaintBoundary隔离消息气泡重绘
- 修复withOpacity已废弃警告

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* perf(chat): 完全解耦输入区和消息列表防止键盘触发重建

将_MessageList和_InputArea提取为独立StatelessWidget,
彻底隔离键盘弹出时对消息列表的影响

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 彩蛋

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 调整调色盘

* 栈

* 栈

* 按照skill严格校验

* 按照skill严格校验

* 按照skill严格校验

* 按照skill严格校验

* fix: 底部导航 Rive 动画卡顿 - 改用 Factory.flutter 渲染

Factory.rive 在 Dialog 中使用 TextureLayer 合成,
Dialog 入场动画重建层树时 TextureLayer 被逐出且无 markNeedsPaint 恢复,
导致播放过程中丢帧。改用 Factory.flutter 使用 Flutter Canvas 渲染,
每帧主动标记重绘,避免此问题。

* fix: 人物小谱页面 Rive 卡顿 - 改用 Factory.flutter 渲染

页面跳转和 Tab 切换卡顿同根因:Factory.rive 的 TextureLayer
在 route/AnimatedSwitcher 层树重建时被冲掉。
改用 Factory.flutter 使用 Canvas 绘制,每帧主动标记重绘解决。

* refactor: 书签标签改为圆点指示器 + PageView 滑动切换

- 移除 _BookmarkTab / _BookmarkTabClipper / _BookmarkSide(约180行)
- 新增 _ProfileDot 8×8 圆点指示器,激活态实心/非激活态空心边框
- 用 PageView 替换 AnimatedSwitcher,支持左右滑动切换
- 圆点叠加在内容区左上角,不遮挡内容

* fix: 圆点移到圆框上方,AppBar 下方顶层

用 Column 布局替代 Stack 叠加,圆点 Row 在内容区顶部,
PageView 通过 Expanded 填充剩余空间,圆点不再遮挡卡片圆角。

* notion

* notion

* 11

* 11

* 11

* 11

* 11

* 重构数据结构

* soga

* 块

* 块

* 块支持换行操作

* 块支持换行操作

* 块支持换行操作

* 块支持换行操作

* 删除

* 今日任务

* 工具栏新增 image 块类型

* 图片块支持点击添加 URL

* 图片块支持从相册/拍照/URL 三种方式添加

* 工具栏新增展开按钮,弹出分类面板(标题/列表/文本/媒体/布局)

* 展开面板移除未实现的类型(toggle/bookmark/equation/布局类)

* 增加工具栏高度(padding 4→8, icon 18→20)

* 笔记列表左滑显示删除按钮

* Restore repository to state at 31d73b9

Uses git read-tree --reset to create a new commit with the same tree
as 31d73b9 (笔记列表左滑显示删除按钮).

* 先规划

* 先规划

* 先规划

* 先规划

* 先规划

* 先规划

* 修理

* 修理

* 修理

* 修理

* 修理

* 更新skill执行指南

* 微调文件路径

* 增加导入md

* refactor: replace BlockType enum + BlockData with sealed class hierarchy

- BlockType enum → sealed class BlockType with 19 subtype classes in type/
- BlockData Map → typed fields on each subtype (HeadingType.level, etc.)
- Each subtype in its own file (type/heading.dart, type/bookmark.dart, etc.)
- JSON serialization fully backward-compatible (tag + data fields)
- All consumers updated: md_to_block, note_repository, block_editor_demo

* refactor: add BlockIdentityFactory to converge identity operations

- Create identity_factory.dart as single entry point for ID/path creation
- Replace all direct BlockId.generate() calls with BlockIdentityFactory.generateId()
- Update identity barrel export

* refactor: add BlockWidgetFactory with O(1) strategy lookup for block rendering

Replace switch-on-type rendering in renderer.dart with BlockWidgetFactory
using the same strategy pattern as MessageWidgetFactory. 11 strategy
implementations (page through image) registered via DI factory.

* refactor: split InlineFormat subclasses into individual part files

Extract 7 InlineFormat subclasses (BoldFormat through ColorFormat) into
their own files using part-of pattern, identical to type/ structure.

* refactor: replace BlockType.fromTag switch with registry map injection

Remove hardcoded switch from fromTag(). Each type registers its own
factory via BlockType.register(). Registration centralized in
registerBlockTypes(), called at app startup alongside registerMessageStrategies.

* refactor: merge BlockType factory registry into type.dart, remove separate DI

The registry map is now a static field directly in BlockType, co-located
with the part directives. Single file to edit when adding a type.

* refactor: replace InlineFormat.fromJson switch with static registry map

Align with BlockType pattern — registry map co-located with part
directives in inline_format.dart.

* refactor: move BlockType deserialization out of base class to separate function

BlockType no longer holds _registry/fromTag — it only defines the type
contract. deserializeBlockType() in its own file handles tag→instance
mapping via switch, keeping each concern separate.

* refactor: move BlockType deserialization to models/block_serializer.dart with map

type/ directory now pure — no serialization concern. Deserialization lives
in models/ alongside its consumer Block.fromJson, using a registry map.

* refactor: converge type registry in type.dart alongside part directives

type.dart now holds both the compile-time type list (part) and the
runtime tag→factory map (typeRegistry) in one file. block_serializer.dart
references typeRegistry instead of duplicating it.

* refactor: strict OOP with injected dependencies across note core

Replace static methods and top-level functions with instance methods
and constructor injection. Introduce BlockCodec (replacing serialization
mixins), BlockTypeRegistry/BlockTypeRegistrar (replacing top-level
typeRegistry map), and convert NoteRepository/EditorState to accept
dependencies via constructors with withDefaults() convenience.

Deleted: block_serializer.dart, deserialize.dart.
New: block_codec.dart, type_registry.dart.
All consumers updated to match the new injection pattern.

* refactor: extract InlineFormat registry into separate class, add RichTextCodec

Remove static _registry map and fromJson factory from sealed class
InlineFormat. Introduce InlineFormatRegistry + InlineFormatRegistrar
for format deserialization (mirroring BlockTypeRegistry pattern).

Remove fromJson factories from Span and RichText. Add RichTextCodec
class that takes InlineFormatRegistry and handles RichText↔JSON
conversion. Wire through BlockCodec and NoteRepository.withDefaults().

* 1

* refactor: strict OOP — eliminate all static/top-level/mutation patterns

- Merge block_id.dart into identity_factory.dart, BlockIdentityFactory
  owns its UUID generator instance
- Delete BlockPath.root unused static constant
- Registry classes accept full factory map at construction (no register()
  mutation); Registrar classes now provide createFactories() returning
  the map instead of post-construction registerAll()
- MdToBlock converted from static methods to instance with injected
  BlockIdentityFactory
- createBlockWidgetFactory() top-level function → BlockWidgetBuilder class
- All consumers updated to use instance-based APIs

* feat: unify dependency assembly via NoteCompositionRoot

Create single composition root at lib/core/note/composition_root.dart
that wires all note core dependencies. Delete NoteRepository.withDefaults()
and make EditorState deps required — consumers now inject from
noteCompositionRoot instead of creating their own instances.

Affects: composition_root.dart, note_repository.dart, EditorState,
renderer.dart, note_panel.dart, storage_analyze_demo.dart

* refactor: unify imports to use core.dart barrel

convert/md_to_block.dart and persistence/note_repository.dart were
importing subdirectory files directly. Switch them to core.dart barrel
for consistency with all other external consumers.

* refactor: add barrel files for convert/ and persistence/, use throughout

Create convert/convert.dart and persistence/persistence.dart barrels.
Update composition_root.dart to use barrels with show clauses. Update
all consumer imports (state.dart, note_panel.dart, storage_analyze_demo.dart)
to go through the new barrels for consistency.

* refactor: eliminate global state — strict OOP final form

- Remove global noteCompositionRoot variable from composition_root.dart
- Add BlockRenderer class wrapping renderBlockContent/textStyleForType
- Create NoteRootScope InheritedWidget for dependency propagation
- Create NoteCompositionRoot in main.dart and inject via NoteRootScope
- Update all consumers (card, editor, note_panel, storage_analyze)
- Delete renderer.dart (logic moved to BlockRenderer)

* chore: remove unused note.dart barrel

* 1.1

* 1.1

* 1.1

* 1.1

* 删除键

* 删除键

* 删除换行

* enter

* 图标

* 图标

* conver

* conver

* skill

* 收回键盘

* 删除键盘bug

* 3. 后续没有点击块

* 1.标题图标

* 导入md文字

* 音量键

* 对话框+发送消息

* 对话框+发送消息

* 总结skill

* 音量键

* feat: add ToolbarMode abstract class and BottomToolbarFactory

* feat: create EditToolbar implementing ToolbarMode

* feat: create ChatBar implementing ToolbarMode

* feat: add toolbarMode state to EditorState

* refactor: use BottomToolbarFactory for bottomNavigationBar

* feat: trigger chat mode on space instead of MessageDialog

* fix: compilation errors - positional onSwitchMode param and missing interface methods

* cleanup: remove unused MessageDialog

* refactor: move mode files to mode/ folder, factory as ChangeNotifier

* feat: add buildBody to mode system, blur + chat bubbles in ChatBar

* fix: BackdropFilter stacking order - blur layer on top of body

* 工具面板

* 优化

* 优化ui

* 优化ui

* 优化ui

* 不滑动切换

* 不滑动切换

* 不滑动切换

* 调整before/after

* 底部导航阴影

* icon

* icon

* icon

* icon

* icon

* icon

* icon

* 建立demo

* 建立demo

* 建立demo

* 建立demo

* 卡顿

* 卡顿

* 长

* nice

* demo

* 颜色

* 颜色

* 颜色

* 颜色

* 颜色ok

* 高度

* 高度

* 弹弹

* 弹弹

* panel的主题色

* panel的主题色

* panel的主题色

* feat: 系统日历同步 + 桌面小组件直达日历页

- 添加 READ_CALENDAR/WRITE_CALENDAR 权限
- 新增 CalendarChannel.kt 原生桥接(插入/删除系统日历事件)
- 新增 CalendarService.dart Flutter 端 MethodChannel
- LabCalendarEvent 增加 systemCalendarEventId 字段
- Provider 增加 syncToSystemCalendar 方法
- 事件抽屉增加同步按钮和已同步标记
- 桌面小组件 deep link 改为 fr://calendar 直接打开日历页

* 删除

* 删除

* 删除

---------

Co-authored-by: zhaoliuxue <2096343460@qq.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
@ZHLX2005 ZHLX2005 merged commit 64be606 into ZHLX2005:master Jun 4, 2026
1 check failed
ZHLX2005 added a commit that referenced this pull request Jun 4, 2026
- 在 PR #61 '2 行 (title+location)' 基础上再加 formatTitleTwoLines:
  * 标题均分成 2 行,每行最多 4 字
  * 标题 > 8 字时第 8 位变 …,再切两行(与 app 端 _splitEvenly 一致)
- styles.xml 同步:maxLines 2 → 3,autoSize 调整为 7~11sp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants