🏗️ 專案概述
應用程式入口點
入口點為 main.dart
,這裡已將相關 "啟動到 ready 流程",封裝到 core/core_application.dart
,而維護上,需要了解的是:
新套件引入
如果引入新套件,並且需要 init 相關動作,請往 CoreApplication
這邊調整,有個 initLibrary 動作集中區。
Application Hooks
裝置生命週期集中區,可自定義邏輯:
whenResumed
- 應用程式從背景回到前台(重新連接聊天、更新資料)whenHidden
- 應用程式進入背景時(登出聊天連接)whenInactive
- 應用程式變為非活躍狀態whenPaused
- 應用程式暫停時whenDetached
- 應用程式完全關閉時whenDeepLink
- 處理深度連結(忘記密碼、群組分享等)
實作位置: CoreApplicationHooks
介面,ValoApplicationHooks
具體實現
專案資料架構
lib/
├── adapters/ # 資料轉換層
├── components/ # 基礎 UI 組件
│ ├── auth/ # 認證相關組件
│ ├── buttons/ # 按鈕組件
│ ├── chat/ # 聊天基礎組件
│ ├── inputs/ # 輸入框組件
│ ├── login/ # 登入組件
│ ├── popup/ # 彈窗組件
│ ├── sheet/ # 底部彈出組件
│ └── welcome/ # 歡迎頁組件
├── config/ # 設定檔
├── core/ # 核心應用邏輯
├── localization/ # 多語言
├── modal/ # 資料模型
├── modalView/ # 視圖狀態管理
├── presentation/ # 頁面展示層
│ ├── layout/ # 佈局組件
│ ├── router/ # 路由設定
│ └── screens/ # 頁面組件
├── services/ # 業務服務層
├── utils/ # 工具函數
└── widgets/ # 業務 Widget 組件
├── add_friend/ # 新增好友
├── chat/ # 聊天功能
├── contacts/ # 聯絡人
├── conversation/ # 對話
├── create_group/ # 建立群組
├── friend/ # 好友功能
├── group/ # 群組功能
├── language/ # 語言切換
├── register/ # 註冊功能
├── terms/ # 條款
├── topic/ # 主題頁面
└── user/ # 使用者功能
- Provider Pattern: 通過
AppProvider.getDependencies()
實現集中式依賴注入 - 數據池:
ValoDataPool
: 核心數據倉庫,管理好友、群組、對話的即時同步ValoExtPool
: 擴展數據管理,處理複雜操作
- 專用狀態:
UserState
、ConversationState
、SearchState
、LoginState
服務層
- ChatService: Agora Chat SDK 整合和管理
- ApiService: 使用 Retrofit/Dio 的 RESTful API 客戶端,具備 Token 管理
- AuthService: 用戶身份驗證和會話管理,採用雙重認證系統
- MediaService: 文件上傳/下載和媒體處理
路由系統
- Auto Route: 具備嵌套路由和守護系統
- 路由守護:
AuthGuard
、TopicGuard
、ConversationGuard
- 深度連結支持: 自定義 URL scheme
valo://
用於外部整合
目錄結構 & 編碼標準
核心目錄
components/
: 基礎可重用 UI 組件(無業務邏輯)config/
: 全域樣式、主題、事件總線、環境配置modal/
: 純數據模型,用於 API 響應modalView/
: UI 相關數據模型和特定屏幕狀態presentation/
: 屏幕、佈局、路由配置services/
: 業務邏輯封裝和 API 整合utils/
: 與業務邏輯無關的通用工具widgets/
: 按領域組織的屏幕級組件 (friend/
,group/
,conversation/
等)
編碼標準
- 顏色: 使用
ValoColor
靜態變量,優先使用withAlpha
而非withOpacity
- 國際化: 所有文本必須使用
easy_localization
,支持三種語言(zh、en、vi) - 通知: 使用
ToastUtil
方法而不直接創建 SnackBar - 底部表單: 使用
BottomSheetUtil.show()
與預定義標頭 - Widget: 盡可能聲明
const
,使用nil
代替無意義的SizedBox
/Container
- 性能: 使用
for
/while
循環而非foreach
/map
,創建StatelessWidget
組件而非_build
方法
多語言支持
- 語言: 中文(zh)、英文(en)、越南文(vi)
- 基礎語言: 英文(en.json)- 所有其他語言必須有對應鍵值
- 實現: 使用
easy_localization
包與 JSON 翻譯文件
認證架構
雙重認證
- REST API token 認證
- 獨立的 Agora Chat SDK 認證
- 跨兩個系統的同步登入/登出
詳細信息請參閱 認證架構文檔。
數據流模式
UI Widget → Provider State → Service Layer → External API/SDK → State Update → UI Refresh
即時更新
- Agora Chat Events → ValoDataPool → UI Components
- 自動對話列表更新和消息傳遞
Chat UI 架構
flutter_chat_ui 整合
- 使用 flutter_chat_ui 函式庫作為聊天介面
- 專用消息建構器:針對不同消息類型(文字、圖片、檔案、自定義)
- 提及系統:群組提及的自定義 TextEditingController,格式為
@{userId}
- 消息適配:
ChatUIAdapter
在 Valo 消息格式和 flutter_chat_ui 格式之間轉換
專案需求 & 功能
核心功能
- 身份驗證: 帶記憶的登入、電子郵件驗證註冊、密碼重設
- 多語言: 中文、英文、越南文支持
- 好友系統: 好友列表、搜索、好友請求
- 群組系統: 創建群組、通過好友消息或分享連結加入
- 聊天功能: 好友聊天、基於角色權限的匿名群組聊天
- 媒體支持: 文字、圖片、檔案、群組邀請
- 設定: 檔案編輯、帳戶安全、黑名單、隱私政策
群組聊天角色
- 擁有者: 可轉讓所有權、設定管理員、擁有所有管理員權限
- 管理員: 可編輯群組檔案、查看成員身份、管理成員
- 成員: 匿名身份、只能編輯自己的匿名檔案
消息類型
- 文字消息、單張圖片、檔案、群組邀請
- 圖片預覽和檔案下載功能
重要實現模式
狀態管理模式
- Provider 階層: 多 Provider 設定,針對不同關注點使用專用 Provider
- 數據同步: ValoDataPool 和 ValoExtPool 管理 Agora SDK 和 UI 之間的即時數據同步
- 狀態隔離: 為聊天編輯器、搜索和消息讀取計數使用獨立的 Provider
事件處理架構
- Agora 事件處理器: 使用唯一事件 ID 註冊以便正確清理
- 消息事件: 為消息成功、錯誤和進度使用獨立處理器
- 群組事件: 群組相關事件(加入、離開、解散)的專用處理器
檔案和媒體處理
- MediaService: 集中式媒體操作(上傳、下載、預覽)
- 檔案類型: 支持帶大小驗證的圖片、文檔
- 預覽系統: 內建檔案預覽與下載功能
擴展方法
- Agora 擴展: ChatGroup、ChatConversation、ChatMessage 的自定義擴展方法
- UI 擴展: 常見 UI 操作的 Context 擴展
- 類型安全: 使用擴展方法實現強類型,提供更好的 API
開發注意事項
環境設定
- Flutter: 3.29.0(Dart 3.7.0)
- 目標平台: iOS、Android
- 目標市場: 越南
- 建制系統: Gradle(Android)、Xcode(iOS)
關鍵依賴
agora_chat_sdk
: 聊天後端整合auto_route
/auto_route_generator
: 聲明式路由與代碼生成provider
: 狀態管理retrofit
/retrofit_generator
: HTTP 客戶端與代碼生成dio
: Retrofit 底層的 HTTP 客戶端easy_localization
: 國際化shared_preferences
: 本地存儲flutter_chat_ui
: 聊天 UI 組件firebase_core
/firebase_messaging
: 推送通知json_serializable
: JSON 序列化代碼生成
代碼品質
- Linting: 使用
flutter_lints
包(參見analysis_options.yaml
) - 分析: 提交前運行
flutter analyze
- 測試: 使用
test_runner.dart
進行分組單元測試的結構化測試 - 生成代碼: 從分析中排除
.g.dart
和.freezed.dart
文件
相關文檔
最後更新: 2025-08-07