---
# System prepended metadata

title: '[Video Note] [Flutter] Flutter Guys - Spotify'
tags: [Flutter, Video Note]

---

Intro
![CleanShot 2025-01-04 at 14.50.30](https://hackmd.io/_uploads/BJiH588Iyl.png)

Dark Or Light Model
![CleanShot 2025-01-04 at 14.51.15](https://hackmd.io/_uploads/SJCD58IL1g.png)

Sign Up Or Sign In
![CleanShot 2025-01-04 at 14.52.12](https://hackmd.io/_uploads/HkPjcUU81e.png)

Register
![CleanShot 2025-01-04 at 14.52.29](https://hackmd.io/_uploads/rJK25U8Lyx.png)

Sign In
![CleanShot 2025-01-04 at 14.52.41](https://hackmd.io/_uploads/B1HacIL81g.png)

Home
![CleanShot 2025-01-04 at 14.54.19](https://hackmd.io/_uploads/Bku7i8U81g.png)

Player
![CleanShot 2025-01-04 at 14.59.45](https://hackmd.io/_uploads/BkRP38UUye.png)

Profile
![CleanShot 2025-01-04 at 15.04.22](https://hackmd.io/_uploads/ryvY688U1l.png)


# Into
![Flutter Guys - Spotify](https://hackmd.io/_uploads/SJXW0I8I1l.jpg)

- 學習在實際項目中應用 Clean Architecture。
- 使用 BLoC（尤其是 Qubit）進行狀態管理，深入掌握 BLoC 的運用。
- 遵循依賴反轉原則，並使用 Get It 作為依賴注入工具，簡化專案複雜度。
- 使用 Dart 的錯誤處理機制。
- Firebase 的 Firestore、Storage 和 Authentication 完整應用。
- 使用 Just Audio 播放音樂。
- 項目設計包括登入/註冊頁面、明暗主題切換、歌曲顯示、收藏頁面等。

# Design

- 使用 Figma 設計應用介面，包括登入/註冊頁、明暗主題切換、主要頁面等。
- 配色和設計以提高使用者體驗為主。

# Project Structure

- Clean Architecture 分為三層：Domain、Data 和 Presentation。
- 各層結構如下：
- **Presentation**: 包括 BLoC、Page 和 Widgets。
- **Domain**: 包括 Entities、Repository 和 Use Cases。
- **Data**: 包括 Data Sources、Repository Implementation 和 Models。
- 額外建立 Core 和 Common 文件夾以管理共用邏輯和設定。

# Theme Of Application

- 在 Core 資料夾內創建 Configs 資料夾以管理主題、樣式和本地化設定。
- 使用 AppColors 類別定義主要顏色，包括主色、背景色（明暗主題）和其他常用顏色。
- 創建 AppTheme 類別，定義明暗主題設定（如主要顏色、背景色、按鈕樣式、字型等）。

# Assets / Fonts

- 在專案根目錄下創建 Assets 資料夾，包括 Fonts、Images 和 Vectors。
- 將字型檔案放入 Fonts 資料夾並在 pubspec.yaml 中定義資源路徑。
- 設定字型權重以便於在專案中呼叫不同字重。
- 在主題中應用自定義字型。

# Splash Page

- 在 Presentation 層創建 Splash 資料夾，內含 BLoC、Page 和 Widgets。
- 建立 SplashPage 類別作為啟動畫面。
- 使用 SVG Picture 顯示 SVG 格式的應用標誌，並透過資源管理類別集中管理資源路徑。
- 隱藏 Debug Banner 並設置預設的首頁為 SplashPage。

# Get Started Page
## 實作 Splash Page 的導向功能

- 將 StatelessWidget 轉為 StatefulWidget，以使用 `initState` 方法。
- 在 `initState` 中建立 `redirect` 函式，使用 `Future.delayed` 設定 2 秒延遲，並透過 `Navigator.pushReplacement` 導向到 Get Started Page。
- 呼叫 `redirect` 函式。

## 建立 Get Started Page

- 新增 `intro/pages/get_started_page.dart` 檔案，定義 `GetStartedPage` 為 StatelessWidget。
- 在 `build` 方法中加入 `Scaffold`，並設定其內容為 `Stack`。

## 顯示背景圖片
![CleanShot 2024-11-29 at 04.59.58](https://hackmd.io/_uploads/SJsRKUUmkg.png)

- 匯入圖片至 `assets/images` 資料夾，命名為 `intro_background.png`。
- 建立 `configs/app_images.dart` 定義 `AppImages` 類別，宣告靜態常數 `introBackground` 作為圖片路徑。
- 在 `GetStartedPage` 使用 `BoxDecoration` 和 `DecorationImage` 顯示背景圖片，並設定 `fit` 為 `BoxFit.cover`。

## 加入黑色透明遮罩

- 在背景圖片上方新增 `Container`，設定 `color` 為黑色，透明度設為 0.15。

## 顯示 Spotify Logo 與文字
![CleanShot 2024-11-29 at 05.12.38](https://hackmd.io/_uploads/BysAn88Q1e.png)

- 使用 `SVGPicture.asset` 顯示 Spotify Logo，並用 `Align` 設定對齊至上方中央。
- 使用兩個 `Text` 元件顯示文字，分別設定不同樣式：
- 第一段文字：字重 `FontWeight.bold`，字體大小 `18`，顏色為白色。
- 第二段文字：字重 `FontWeight.w500`，字體大小 `13`，顏色為灰色。
- 用 `SizedBox` 調整文字之間的間距。

## 加入按鈕元件
![CleanShot 2024-11-29 at 05.28.29](https://hackmd.io/_uploads/r1FYxPUXJe.png)

- 在 `widgets/button/basic_app_button.dart` 中建立通用按鈕元件 `BasicAppButton`，使用 `ElevatedButton`。
- 提供參數 `onPressed`、`title`，並新增可選參數 `height`（預設為 80）。
- 在 `GetStartedPage` 中使用 `BasicAppButton` 顯示按鈕，設定標題為 "Get Started"，並使用 `SizedBox` 調整按鈕與文字間距。

## 優化與調整
![CleanShot 2024-11-29 at 05.29.37](https://hackmd.io/_uploads/SJRReDL7Jl.png)

- 使用 `const` 關鍵字優化元件以減少重建。
- 修正警告訊息並保持程式碼整潔。
# Choose Light-Dark Mode Page
![CleanShot 2024-12-16 at 14.37.08](https://hackmd.io/_uploads/rJEnqSTV1l.png)

## 建立選擇模式頁面 (Choose Mode Page)
- 新增資料夾 `choose_mode` 並建立 `page/choose_mode.dart` 文件。
- 建立 `ChooseModePage` 類別，返回 Scaffold 結構。

## 導航到選擇模式頁面
- 在「Get Started」按鈕點擊事件中使用 `Navigator.push`，透過 `MaterialPageRoute` 導航到 `ChooseModePage`。
- 修正按鈕點擊失效問題，將覆蓋按鈕的容器移到 `Stack` 結構的底層。

## 設計選擇模式頁面
- 匯出背景圖片並存入 `assets/images` 資料夾。
- 在資產管理類別中定義靜態常數 `chooseModeBackground`。
- 從 Get Started 頁面複製結構，修改背景圖片為 `chooseModeBackground`。
- 修改標題文字為 "Choose Mode"，增加按鈕間距，移除多餘文字，新增兩個按鈕。

## 圖示與樣式設定
- 匯出太陽與月亮圖示，並在向量管理類別中定義靜態常數 `sun` 和 `moon`。
- 為按鈕新增圓形容器，使用 `BoxDecoration` 設定形狀與顏色。
- 加入背景模糊效果，使用 `BackdropFilter` 搭配 `ImageFilter.blur`。
- 中心加入圖示，透過 `SvgPicture.asset` 顯示。
- 下方加入文字標籤，設定字體樣式與顏色。

## 初始化主題切換邏輯
- 新增 `flutter_bloc`、`hydrated_bloc` 和 `path_provider` 至 `pubspec.yaml`。
- 在 `main.dart` 初始化 `HydratedBloc`，設定存儲目錄。
- 建立 `ThemeCubit` 類別，繼承 `HydratedCubit` 並管理 `ThemeMode` 狀態。
- 實作方法 `updateTheme` 用於切換主題。

## 主題切換邏輯整合
- 在 `main.dart` 使用 `MultiBlocProvider` 注入 `ThemeCubit`。
- 用 `BlocBuilder` 監聽主題變化並更新 `MaterialApp` 的 `themeMode`。
- 在選擇模式頁面，將按鈕包裝為 `GestureDetector`，使用 `context.read<ThemeCubit>().updateTheme()` 切換主題。

## 測試與調整
- 點擊按鈕切換主題後，應保存主題設定並在應用程式重新啟動後生效。
- 目前缺少顯示選擇狀態的設計，但基本主題切換邏輯已完成。
# Logic Of Light-Dark Mode 
![CleanShot 2024-12-25 at 21.38.58](https://hackmd.io/_uploads/HyaZjKFrJx.png)

## 初始化 `hydrated_bloc` 和依賴套件

- 使用 `hydrated_bloc` 儲存主題模式，不需 `shared_preferences`。
- 添加 `flutter_bloc`、`hydrated_bloc` 和 `path_provider` 套件。
- 將套件加入 `pubspec.yaml` 並執行下載。

## 初始化 `hydrated_bloc` 在主檔案

- 在 `main.dart` 初始化 `hydrated_bloc`。
- 匯入 `hydrated_bloc`、`foundation` 和 `path_provider`。
- 修改代碼中的 `App` 為 `MyApp` 並添加必要的 `const`。

## 建立 Theme Cubit

- 在 `presentation` 資料夾中新增 `bloc` 資料夾與 `theme_cubit.dart` 檔案。
- 建立 `ThemeCubit` 類別，繼承 `HydratedCubit<ThemeMode>`。
- 定義初始狀態為 `ThemeMode.system`。
- 建立 `updateTheme` 方法，接受 `ThemeMode` 參數並發出狀態。

## 設置 MultiBlocProvider

- 在 `main.dart` 使用 `MultiBlocProvider` 包裹 `MaterialApp`。
- 注入 `ThemeCubit`，以監聽主題模式的變更。
- 使用 `BlocBuilder` 包裹 `MaterialApp`，根據主題模式設定 `theme` 和 `darkTheme`。

## 修改選擇模式頁面

- 在選擇模式頁面，將容器包裹在 `GestureDetector` 中。
- 使用 `context.read<ThemeCubit>().updateTheme` 呼叫 `updateTheme` 方法。
- 為不同的容器傳遞 `ThemeMode.light` 和 `ThemeMode.dark`，以切換主題模式。
- 測試功能確認主題模式切換是否正常工作。
# SigninOr Signup Page
![CleanShot 2024-12-26 at 10.05.55](https://hackmd.io/_uploads/B1_G54cSkg.png)

## 實作登入與註冊頁面

- 根據設計，首先需要實作登入或註冊頁面。
- 匯出 Figma 設計圖，將圖像導出為 SVG（如頂部與底部圖案）和 PNG 格式（認證背景圖）。
- 在專案中創建 `authentication` 資料夾並新增 `sign_up_or_sign_in.dart` 檔案。
- 在頁面中使用 `Scaffold` 和 `Stack`，並使用對應的對齊來顯示設計圖案。

---

## 設定頁面背景與圖案

- 使用 `Stack` 來實現背景圖案，並使用 `alignment` 設置圖案的位置。
- 定義靜態常數來存儲頂部與底部圖案路徑，並加載對應的 SVG 圖片。
- 設定圖片為底部和左側的背景，確保顯示正確。

---

## 顯示應用程式內容

- 在頁面中使用 `Column` 顯示應用的內容，包括 logo、文字和按鈕。
- 使用 `SizedBox` 來設置各元素之間的間距。
- 使用 `Text` 來顯示文字，並設置對應的字體大小、顏色與間距。
- 根據設計，顯示兩個按鈕並設置相應的字體大小、顏色和間距。

---

## 處理主題切換問題

- 針對亮暗模式，使用條件來設置文字顏色（白色或黑色）。
- 創建 `isDarkMode` 擴展函數來檢查當前的主題並返回適當的顏色。
- 在頁面中使用 `context.read<ThemeCubit>().updateTheme` 來檢查主題並設置文字顏色。

---

## 實作回退按鈕

- 在 `widgets` 資料夾中創建 `BasicAppBar` 作為回退按鈕的共用元件。
- 設定 `AppBar` 背景色為透明，並設置回退按鈕圖標。
- 設置按鈕顏色依據暗色或亮色主題變更，並處理按下事件調用 `Navigator.pop` 返回上一頁。

---

## 測試與調整

- 測試頁面在不同主題模式下的顯示，確保圖案與顏色切換正確。
- 測試登入和註冊頁面是否能夠正常顯示並實現功能。
# Signup Page & Signin Page
![CleanShot 2024-12-27 at 06.09.10](https://hackmd.io/_uploads/rJ-QVLsB1g.png)

## 建立註冊與登入頁面
- 建立 SignUp 和 SignIn 頁面，分別處理註冊與登入功能。
- 使用 Scaffold 作為頁面框架，透過 Column 堆疊元件。
- 設置導航邏輯，實現頁面間跳轉功能。

## 自訂 AppBar 與樣式
- 建立 BasicAppBar 作為自訂的 AppBar 元件。
- 支援 PreferredSizeWidget 接口，設置標題與背景透明。
- 在標題中顯示 SVG Logo，支援調整大小與居中顯示。

## 設計輸入欄位
- 建立全名、電子郵件與密碼的 TextField 輸入框。
- 使用 InputDecoration 自訂樣式，設置圓角邊框與提示文字樣式。
- 預設內容間距與邊框顏色，支援暗色與亮色主題。

## 基本按鈕與文字連結
- 自訂按鈕樣式，實現按鈕文字與點擊事件。
- 建立文字連結，如「Sign In」和「Register Now」按鈕。

## 暗色與亮色模式支援
- 根據主題動態調整元件顏色，如文字與按鈕背景。
- 在暗色與亮色主題中分別設置輸入框與提示文字的樣式。

## 頁面間的邏輯與導航
- 使用 Navigator.push 和 Navigator.pushReplacement 管理頁面導航。
- 註冊頁面與登入頁面間相互跳轉，實現流暢的使用者體驗。

## 優化與共用元件
- 將重複元件提取為獨立組件，提升程式碼可讀性與可維護性。
- 在共用樣式檔中設置輸入框樣式，方便統一修改設計。
# Firebase Setup & Logic Of Authentication & Service Locator
## Firebase CLI 設定
- 使用 Firebase CLI 來設定專案，建議選擇 Standalone Binary 進行安裝。
- 登入 Firebase 帳戶，使用 `firebase login` 命令，確認登入成功。
- 使用 `firebase init` 命令來初始化 Firebase 專案，選擇專案名稱和平台(Android/iOS)。
```
dart pub global activate flutterfire_cli 
```
```
flutterfire configure 
```
## Firebase 初始設定
- 在專案的主程式檔(main.dart)中，初始化 Firebase。
- 使用 `Firebase.initializeApp` 並指定 options，從 Firebase 的 options 檔案中讀取設定。
- 確保 `firebase_core` 套件已在 `pubspec.yaml` 中添加。

## 架構與 Domain Layer
- 遵循 Clean Architecture，先從 Domain Layer 開始實作邏輯。
- 在 entities 資料夾中新增 `authentication`，建立 `user_entity` 類別。
- 定義必要的欄位（例如 fullName、email、userId）及其建構子(Constructor)。
- 在 repository 資料夾中新增 `authentication`，定義 `AuthenticationRepository` 抽象類別，包含 signUp 和 signIn 方法。

## Data Layer 設定
- 在 Data Layer 中新增 `authentication` 資料夾，包含 models、repositories 和 sources。
- 在 models 資料夾中建立 `create_user_request` 類別，定義 fullName、email 和 password 欄位。
- 在 sources 中建立 `AuthenticationFirebaseService` 抽象類別，定義 signUp 和 signIn 方法。
- 建立 `AuthenticationFirebaseServiceImplementation` 類別，實作 Firebase 認證的邏輯，包含錯誤處理和 Firebase 的 `createUserWithEmailAndPassword` 方法。

## 使用 Service Locator
- 使用 `get_it` 套件實現依賴注入，避免手動創建實例造成代碼複雜度增加。
- 建立 `service_locator.dart`，創建一個全域的 Service Locator 實例（例如 `final sl = GetIt.instance`）。
- 定義 `initializeDependencies` 方法，註冊單例服務，如 `AuthenticationFirebaseService` 和 `AuthenticationRepository`。
- 在主程式中呼叫 `initializeDependencies`，於執行應用程式前初始化依賴。

## Repository 實作
- 在 `data/repositories` 中建立 `AuthenticationRepositoryImplementation` 類別，實作 `AuthenticationRepository` 抽象類別的方法。
- 使用 Service Locator 訪問 `AuthenticationFirebaseService`，並調用其 signUp 和 signIn 方法。
- 使用 `CreateUserRequest` 類別封裝從使用者獲取的數據並傳遞至 Firebase 方法。

## 錯誤處理
- 在 Firebase Service 和 Repository 中添加錯誤處理邏輯，使用 try-catch 块處理 Firebase 認證異常。
- 針對常見錯誤如無效的 email 或密碼提供用戶提示。
# UseCases Setup - Calling Signin / Signup UseCases 
## 定義 Use Case 抽象類別
- 建立 `use_case` 資料夾與 `use_case.dart` 文件。
- 創建抽象類別 `UseCase`，接受泛型參數 `Type`（回傳值類型）與 `Params`（輸入參數類型）。
- 定義 `call` 方法，回傳 `Type`，接受 `Params` 作為輸入。

## 設計 Sign Up Use Case
- 在 `domain/use_cases/authentication` 中新增 `sign_up_use_case.dart`。
- 繼承 `UseCase`，設置 `Type` 為 `Either` 類別，`Params` 為 `CreateUserRequest` 類別。
- 實作 `call` 方法，呼叫 `AuthenticationRepository` 的 `signUp` 方法。
- 修改 `AuthenticationRepository` 的 `signUp` 方法回傳類型為 `Either`，在成功與失敗情況下回傳不同訊息。

## 註冊 Sign Up Use Case
- 在 Service Locator 註冊 `SignUpUseCase`。
- 確保在應用程式中可以正常調用。

## 使用 Sign Up Use Case
- 在 `presentation/authentication/sign_up_page.dart` 中實作相關功能。
- 建立 `TextEditingController` 管理使用者輸入的 `fullName`、`email` 和 `password`。
- 呼叫 `SignUpUseCase`，傳入 `CreateUserRequest`，並使用 `Either.fold` 檢查結果，成功時導向 Root 頁面，失敗時顯示錯誤訊息。

## Firebase 設定與測試 Sign Up
- 在 Firebase Console 啟用 Email/Password 註冊方式。
- 測試弱密碼與已存在的 Email 錯誤處理，確認成功時會導向 Root 頁面。
![CleanShot 2024-12-28 at 09.02.19](https://hackmd.io/_uploads/r18BRphrke.png)

## 設計 Sign In Use Case
- 新增 `sign_in_use_case.dart`，邏輯類似 `sign_up_use_case.dart`。
- 定義 `SignInUserRequest` 類別，僅包含 `email` 與 `password`。
- 修改 `AuthenticationRepository` 的 `signIn` 方法回傳類型為 `Either`，處理成功與錯誤情況。
- 錯誤類型包括無效 Email（無使用者）與無效憑證（密碼錯誤）。

## 註冊 Sign In Use Case
- 在 Service Locator 註冊 `SignInUseCase`，確保可用於應用程式中。

## 使用 Sign In Use Case
- 在 `presentation/authentication/sign_in_page.dart` 中實作相關功能。
- 建立 `TextEditingController` 管理使用者輸入的 `email` 與 `password`。
- 呼叫 `SignInUseCase`，傳入 `SignInUserRequest`，並使用 `Either.fold` 檢查結果，成功時導向 Root 頁面，失敗時顯示錯誤訊息。

## 測試 Sign In
- 測試無效 Email、密碼錯誤以及成功登入情況，確認正確導向或顯示錯誤訊息。
- ![CleanShot 2024-12-28 at 09.26.24](https://hackmd.io/_uploads/B1NkVChH1x.png)
![CleanShot 2024-12-28 at 09.27.30](https://hackmd.io/_uploads/ryvXNAhS1e.png)

# Upload Songs To FireStorage ＆ Cloud FireStore Collections ＆ Adding Information Of User To FireStore Collection
## 已完成的功能實作

- 完成 Authentication 領域層與資料層的實作，包含 Service Locator 和 Use Case 整合。

## Firebase Storage 設定與檔案上傳

- 開啟 Firebase Console，完成 Storage 初始化設定。
- 建立資料夾 songs 與 covers，分別上傳歌曲檔案與封面圖片。
- 測試圖片檔案 URL，移除 token 後發現無權限問題。
- 修改 Storage Rules 設定 read: true、write: false，解決無權限問題。

## Firebase Firestore 設定與 Songs Collection 建立

- 開啟 Firebase Console，啟用 Firestore Database。
- 建立 songs 集合並新增文件，使用 Auto ID。
- 新增欄位 title、artist name、duration、release date，儲存歌曲相關資料。

## User Collection 自動建立與 Sign-up 整合

- 新增 Firestore 依賴項，實現 users 集合自動建立。
- 在資料層的註冊功能中，透過 add 方法新增文件。
- 文件內容包含 name 和 email，從 Sign-up 表單抓取用戶輸入的名稱與郵件。
- 修正 Firestore Rules，檢查 request.auth != null，允許合法寫入操作。
- 測試結果顯示用戶資料成功寫入 users 集合，包含正確名稱與電子郵件。
# Home Page - Fetching Songs - Display Songs Using Bloc,....
![CleanShot 2024-12-30 at 11.06.10](https://hackmd.io/_uploads/Skz8AtkUke.png)

## 建立 Cloud Firestore 集合與專案規劃
- 完成專案需實現三個頁面：首頁、音樂播放器頁面與使用者個人頁面。
- 首要任務是實作首頁。

## 匯出資源
- 將卡片元件匯出為 SVG 格式，儲存至 `assets/vectors` 資料夾。
- 將圖像匯出為 PNG 格式，儲存至 `assets/images` 資料夾並命名為 "artist"。

## 修改路由與首頁檔案
- 將路由檔案名稱從 `root` 改為 `home`。
- 將路由頁面從 `rootPage` 改為 `homePage`，並同步修改其他頁面設定。

## 建立 App Bar
- 從註冊或登入頁面複製 App Bar，並貼到首頁。
- 使用 `hideBack` 布林參數控制是否顯示返回按鈕，`true` 不顯示，`false` 顯示。

## 首頁卡片元件
- 建立 `HomeTopCard` 小元件，設定卡片大小與內容。
- 使用 `SvgPicture.asset` 加載 SVG 圖像，定義靜態常量 `homeTopCard` 儲存資源路徑。

## 使用 Stack 組合圖像與卡片
- 在卡片上方顯示圖像，使用 `Stack` 包裹 SVG 卡片與圖像。
- 定義靜態常量 `homeArtist` 儲存圖像資源路徑。
- 使用 `SizedBox` 調整卡片與圖像大小，並加上右側間距。

## 實作 Tab Bar
- 新增 `TabBar` 元件，定義四個標籤：新聞、影片、藝術家、Podcast。
- 使用 `TabController` 控制標籤，設定長度為 4。
- 將元件類型改為 `StatefulWidget`，在 `initState` 中初始化 TabController。

## 自訂 Tab Bar 樣式
- 設定文字顏色，深色模式顯示白色文字，淺色模式顯示黑色文字。
- 增加文字粗細與字體大小，設定標籤指示器顏色為主要顏色。
- 使用 `EdgeInsets.symmetric` 設定水平與垂直間距。

---
## 建立歌曲實體 (Song Entity)
- 在 `domain/entities` 資料夾中建立 `song` 資料夾，新增 `song.dart` 文件。
- 定義歌曲實體包含以下欄位：`title`、`artist` (字串)，`duration` (數字)，`releaseDate` (時間戳記)。
- 為實體建立建構子。

## 建立歌曲模型 (Song Model)
- 在 `data/models` 資料夾中建立 `song` 資料夾，新增 `song.dart` 文件。
- 模型包含與實體相同的欄位，並實作 `fromJson` 方法將 JSON 轉換為模型。
- 定義擴展方法將模型轉換為實體。

## 定義歌曲存取介面
- 在 `domain/repositories` 資料夾中建立 `song` 資料夾，新增 `song_repository.dart` 文件。
- 定義抽象類別 `SongsRepository`，包含方法 `getNewsSongs`，回傳型別為 `Either`。

## 實作 Firebase 資料服務
- 在 `data/sources` 資料夾中建立 `songs` 資料夾，新增 `song_firebase_service.dart` 文件。
- 定義抽象類別 `SongFirebaseService`，包含方法 `getNewsSongs`。
- 實作該抽象類別，透過 Firebase Firestore 存取歌曲集合，按 `releaseDate` 遞減排序，取最新的三筆文件。
- 使用迴圈將每個文件的 JSON 資料轉換為模型，然後轉換為實體並加入列表。

## 錯誤處理
- 將資料存取邏輯包裹於 `try-catch` 區塊中，成功時回傳 `Either.right`，錯誤時回傳 `Either.left`，並提供錯誤訊息。

## 實作歌曲資料儲存庫
- 在 `data/repositories` 資料夾中建立 `song` 資料夾，新增 `song_repository_implementation.dart` 文件。
- 建立 `SongRepositoryImplementation` 類別，實作 `SongsRepository`。
- 在 `getNewsSongs` 方法中呼叫 `SongFirebaseService` 的實作。

## 建立歌曲用例 (Use Case)
- 在 `domain/use_cases` 資料夾中建立 `song` 資料夾，新增 `get_news_songs.dart` 文件。
- 建立 `GetNewsSongsUseCase` 類別，實作用例邏輯，調用儲存庫的 `getNewsSongs` 方法。

## 註冊依賴注入
- 在服務定位器中註冊 `SongFirebaseService`、`SongRepositoryImplementation` 和 `GetNewsSongsUseCase`。
- 確保依賴關係正確連結並可供全域存取。

---
## 實作 Bloc 狀態管理
- 在 `bloc` 資料夾建立 `news_songs_state.dart` 和 `news_songs_cubit.dart` 檔案。
- 定義狀態包括 `NewsSongsState`（抽象基類）、`NewsSongsLoading`（載入中）、`NewsSongsLoaded`（包含歌曲列表資料）、`NewsSongsLoadFailure`（載入失敗）。
- 在 Cubit 中實作 `getNewsSongs` 方法，呼叫用例，根據結果發送相應狀態。

## 建立內容展示元件
- 在 `widget` 資料夾建立 `news_songs.dart`。
- 使用 `BlocProvider` 注入 `NewsSongsCubit`，在元件渲染時調用 `getNewsSongs` 方法。
- 使用 `BlocBuilder` 根據狀態渲染 UI，包括載入動畫、歌曲列表和空白容器。

## 圖片與歌曲資訊顯示
- 使用 `Container` 與 `BoxDecoration` 顯示圖片，並設定圓角。
- 圖片 URL 根據 `artist` 和 `title` 動態生成。
- 在圖片下方展示歌曲名稱與歌手名稱，設置字體加粗與適當間距。

## 播放按鈕設計
- 在圖片右下角使用 `Transform` 設置圓形播放按鈕。
- 按鈕顏色與應用程式主題模式（明亮或黑暗）同步。
- 在按鈕內放置播放圖示，適應應用程式配色。

## Tab 與新聞內容整合
- 在首頁使用 `TabBarView`，將 `NewsSongs` 元件作為其中一個子頁籤。
- 為其他頁籤（例如影片、藝術家、Podcast）暫時使用空容器。
- 使用 `SizedBox` 包裹 `TabBarView` 以解決高度相關問題。

---

## 播放清單資料處理
- 在 Repository 中新增 `getPlaylist` 方法，從 Firestore 獲取所有歌曲資料（無需限制數量）。
- 在 Use Case 資料夾中新增 `getPlaylist` 使用案例，並實現邏輯以呼叫 `getPlaylist` 方法。
- 在 Service Locator 註冊 `getPlaylist` 使用案例以便後續使用。

## 播放清單狀態管理
- 在 Bloc 資料夾新增 `playlist_cubit.dart` 和 `playlist_state.dart`。
- 定義狀態，包括 `PlaylistLoading`（載入中）、`PlaylistLoaded`（包含歌曲列表資料）、`PlaylistLoadFailure`（載入失敗）。
- 在 Cubit 中實作 `getPlaylist` 方法，呼叫用例並根據結果發送相應狀態。

## 播放清單元件設計
- 在 Widgets 資料夾新增 `playlist.dart`，使用 BlocProvider 注入 PlaylistCubit。
- 使用 BlocBuilder 根據 PlaylistCubit 的狀態渲染 UI，包含載入動畫和歌曲列表。
- 播放清單列表以 ListView 顯示，每個項目包含歌曲名稱、歌手名稱、播放按鈕和喜好按鈕。

## 播放清單標題與更多按鈕
- 使用 Column 元件顯示播放清單標題與「查看更多」按鈕。
- 播放清單標題字體加粗，字號較大；「查看更多」字體較小，顏色與應用主題一致。
- 增加左右與上下間距以調整外觀。

## 播放清單歌曲項目設計
- 使用 Row 元件佈局，包含播放按鈕、歌曲資訊和喜好按鈕。
- 播放按鈕以圓形容器顯示，背景顏色根據主題變化，內嵌播放圖示。
- 歌曲名稱字體加粗，歌手名稱字體較細，並有適當間距。
- 加入時長顯示，字體與歌曲資訊一致。

## 喜好按鈕設計
- 使用 IconButton 作為喜好按鈕，顏色與應用程式主題一致。
- 提供基礎樣式與交互行為，喜好邏輯將於稍後實作。

## 整合播放清單至首頁
- 在首頁新增 Playlist 區域，顯示於 TabBarView 下方。
- 播放清單區域設置適當的間距與佈局，使整體視覺效果統一。
- 測試應用程式以確認播放清單功能與外觀正常運作。
# Song Player Page - Using Bloc To Manage State Of Playing Song
![CleanShot 2025-01-01 at 20.27.37](https://hackmd.io/_uploads/SyapV3f81e.png)

## 建立 `SongPlayer` 頁面與結構
- 建立 `song_player` 資料夾，內含 `pages` 和 `block` 資料夾。
- 在 `pages` 資料夾中建立 `song_player.dart` 文件，建立 `StatelessWidget` 的 `SongPlayerPage` 類別。
- `SongPlayerPage` 使用 `Scaffold` 作為基礎結構。

## 導航到 `SongPlayerPage`
- 在首頁 (`HomePage`) 的 `new songs` 和 `playlist` 頁面，將項目包裹在 `GestureDetector` 中。
- 使用 `Navigator.push` 和 `MaterialPageRoute` 導航到 `SongPlayerPage`。

## 添加 AppBar
- 在 `SongPlayerPage` 中實作基本的 AppBar。
- 設定標題為 "Now Playing" 並調整樣式。
- 添加右側的更多選單按鈕，使用 `Icon` 和 `IconButton`。

## 顯示歌曲封面
- 在 `SongPlayerPage` 中，傳入 `SongEntity` 對象，透過建構函數接收。
- 建立 `SongCover` 小部件，使用 `Container` 和 `NetworkImage` 顯示歌曲封面。
- 添加圖片樣式，如圓角、縮放、間距。

## 顯示歌曲細節
- 建立 `SongDetail` 小部件，顯示歌曲名稱、藝術家名稱和喜歡按鈕。
- 調整標題字體大小，排列樣式設為 `MainAxisAlignment.spaceBetween`。
- 喜歡按鈕使用 `IconButton`，切換圖標為 `Icons.favorite_outline`。

## 優化設計
- 在 `SingleChildScrollView` 中使用 `Column` 結構。
- 在封面與細節間添加空隙。
- 添加 `Padding` 調整頁面間距。
- 修改 `Playlist` 頁面的喜歡按鈕樣式以保持一致性。

## Slider 和歌曲時間顯示
- 使用 Bloc 管理狀態，實時更新歌曲的播放進度。
- 在 `bloc` 資料夾新增 `SoundPlayerCubit` 和 `SoundPlayerState` 文件。
- 定義三種狀態：`loading`、`loaded`、`failure`。
- 使用 `just_audio` 庫實作歌曲播放邏輯。

## `SoundPlayerCubit` 的實作
- 初始化 `AudioPlayer` 實例。
- 定義 `loadSong` 方法載入歌曲 URL，更新狀態為 `loaded` 或捕捉錯誤設為 `failure`。
- 定義 `playOrPauseSong` 方法，根據播放狀態呼叫 `play` 或 `pause` 方法。
- 定義 `songDuration` 和 `songPosition` 變數儲存歌曲總時長與目前位置。
- 使用 `stream` 監聽歌曲播放位置與時長，並更新 UI。

## 在 UI 中整合 Bloc
- 使用 `BlocProvider` 注入 `SoundPlayerCubit`。
- 呼叫 `loadSong` 並傳入歌曲的 URL。
- 修改 URL 格式區分封面圖與 MP3 檔案。

## 顯示 Slider 和時間
- 建立新元件 `SongPlayer`，使用 `BlocBuilder` 更新狀態。
- 狀態為 `loading` 時顯示 `CircularProgressIndicator`，為 `loaded` 時顯示進度條。
- 使用 `Slider` 顯示播放進度，`value` 設為目前播放位置，`min` 設為 0，`max` 設為歌曲總時長。
- 顯示目前播放位置與總時長，格式化時間為 `分鐘:秒` 格式。

## 播放/暫停按鈕
- 建立圓形按鈕，使用 `Icon` 顯示播放或暫停圖示。
- 根據播放狀態切換圖示，正在播放時顯示 `Icons.pause`，未播放時顯示 `Icons.play_arrow`。
- 使用 `GestureDetector` 包裹按鈕，實現點擊播放或暫停功能。

## 優化設計與測試
- 修正歌曲 URL，將 `cover` 改為 `songs`。
- 重啟應用測試進度條與播放按鈕，確認功能正常。
- 測試結果：播放器功能完成，播放與暫停運作良好。
# Logic Of Favorite Songs
## Firebase 鑑權與資料結構設計
- 使用 Firebase Authentication 獲取已登入使用者的 userID
- 每位使用者的文件包含子集合 favorites，存放收藏的歌曲
- 修改 signUp 流程，使用 userID 作為自訂文件 ID

## 資料庫操作與方法設計
- 在 SongRepository 中新增 addOrRemoveFavoriteSong 方法
- 在 SongFirebaseService 中覆寫該方法，實現歌曲收藏的新增或移除
- 檢查 favorites 集合中是否已有指定歌曲 ID，決定新增或刪除
- 使用 FirebaseFirestore 的 add 方法新增歌曲收藏，delete 方法刪除收藏

## 判斷歌曲是否為收藏
- 新增 isFavoriteSong 方法，檢查指定 songID 是否存在於 favorites 集合
- 使用 where 過濾指定歌曲，返回布林值表示是否已收藏

## 使用案例 (Use Cases)
- 創建 addOrRemoveFavoriteSongUseCase 處理新增或移除收藏
- 創建 isFavoriteSongUseCase 檢查歌曲是否為收藏
- 註冊上述使用案例於服務定位器

## 更新歌曲實體與模型
- 在歌曲實體與模型中新增屬性 isFavorite 和 songID
- 在 SongFirebaseService 的 getNewSongs 和 getPlaylist 方法中設置這些屬性

## 收藏按鈕 (Favorite Button)
- 使用 Bloc 建立 FavoriteButtonCubit 處理收藏按鈕的狀態管理
- 收藏按鈕初始狀態為 FavoriteButtonInitial，狀態更新為 FavoriteButtonUpdated
- 根據 isFavorite 的值顯示實心或空心收藏圖標
- 在按鈕點擊事件中調用 addOrRemoveFavoriteSongUseCase 切換收藏狀態

## UI 組件化設計
- 將收藏按鈕封裝為通用組件，接收 songEntity 決定按鈕狀態
- 點擊按鈕觸發 updateFavoriteButton 方法處理收藏切換
- 在 Playlist 和 MusicPlayerPage 中調用該通用組件

## Firebase 儀表板驗證
- 在 Firebase 儀表板中驗證 favorites 集合的更新
- 確認收藏按鈕觸發後，歌曲文件正確新增或移除
- 文件包含 songID 和 addedDate
# User Profile Page - Display User Info -Display Favorite Songs - Remove Favorite Song
![CleanShot 2025-01-04 at 14.49.15](https://hackmd.io/_uploads/rJmZqIIUJe.png)

## 建立 Profile 頁面基本結構
- 新增 `profile` 資料夾，建立 `pages` 資料夾與 `profile.dart` 文件。
- 建立無狀態類別，回傳 `Scaffold` 作為頁面框架。
- 在首頁 `AppBar` 中加入 `IconButton`，使用 `Navigator` 導向 `Profile` 頁面。
- 使用 `Icons.person` 作為圖示。

## Profile 頁面設計與區塊劃分
- 頁面分為使用者資訊與收藏歌曲清單兩部分。
- 使用 `AppBar`，標題設為 `Profile`，支援淺色與深色模式背景顏色。
- 頁面主體使用 `Column`，上方顯示使用者資訊，下方顯示歌曲清單。

## 使用者資訊區塊設計
- 建立 `profileInfo` 小元件，回傳帶裝飾的 `Container`。
- 設置深色模式灰色與淺色模式白色的背景顏色。
- 加入底部左右邊界的圓角效果。
- 從設計工具獲取正確顏色代碼，修正顏色設置。

## 顯示使用者資訊內容
- 在 `profileInfo` 顯示頭像、全名和電子郵件。
- 暫不顯示追蹤數與粉絲數。

## 建立 `getUser` 方法
- 在身份驗證資料夾新增 `getUser` 方法，從 Firebase Firestore 查詢特定使用者資料。
- 使用 `DocumentSnapshot` 獲取資料。

## 建立與處理 User Model
- 在模型資料夾新增 `UserModel` 類別，包含全名、電子郵件與頭像 URL。
- 提供 `fromJson` 方法進行 JSON 轉換。
- 加入方法將 `UserModel` 轉為 `UserEntity`。
- 若 `photoURL` 為空，設置預設頭像 URL。

## 錯誤處理與返回值
- 使用 `try-catch` 捕捉錯誤，返回錯誤訊息。
- 返回 `Either` 類型，右側包含 `UserEntity`，左側包含錯誤訊息。

## 註冊 UseCase 並整合至 Profile 頁面
- 建立 `getUser` UseCase，註冊至依賴注入系統。
- 在 Profile 頁面呼叫 UseCase 獲取使用者資訊並更新顯示。



## 建立 Profile Info 的狀態管理
- 在 `profile` 資料夾新增 `bloc` 資料夾，並建立 `profile_info_cubit.dart` 文件。
- 創建抽象類別，定義 `ProfileInfoLoading`、`ProfileInfoLoaded` 和 `ProfileInfoFailure` 三種狀態。

## 實現 ProfileInfoCubit
- 初始狀態設為 `ProfileInfoLoading`。
- 定義 `getUser` 方法，使用 `fold` 方法處理返回值。
- 左側返回 `ProfileInfoFailure`，右側返回 `ProfileInfoLoaded`，並傳遞 `UserEntity`。

## 在 Profile 頁面注入 Cubit
- 使用 `BlocProvider` 注入 `ProfileInfoCubit` 並調用 `getUser` 方法。
- 在 `Container` 中使用 `BlocBuilder` 監聽狀態變化。

## 顯示使用者資訊
- 使用 `Container` 顯示頭像，設置圓形圖片並調整寬高。
- 顯示電子郵件與全名，並調整字體樣式。

## 建立 Favorite Songs 的邏輯
- 在歌曲資料庫層新增 `getUserFavorites` 方法，從 `FirebaseFirestore` 查詢使用者收藏的歌曲 ID。
- 根據歌曲 ID 查詢 `songs` 集合，並轉換為 `SongEntity`。
- 捕捉錯誤並返回失敗訊息。

## 註冊 Favorite Songs UseCase
- 在 UseCase 資料夾新增 `GetUserFavoriteSongs`，封裝收藏歌曲的查詢邏輯。
- 在依賴注入系統中註冊 `GetUserFavoriteSongs` UseCase。

## 整合 Favorite Songs 至 Profile 頁面
- 使用 `GetUserFavoriteSongs` 獲取使用者收藏歌曲列表。
- 在頁面下方顯示歌曲清單並設置適當的 UI 樣式。

## 顯示使用者收藏的歌曲
- 在 `profile` 頁面創建 `Cubit` 管理顯示使用者收藏歌曲。
- 定義 `Loading`、`Loaded` 和 `Failure` 狀態。
- 在 `FavoriteSongsCubit` 中創建 `getFavoriteSongs` 方法，調用 `GetFavoriteSongs` UseCase 並處理結果。

## 使用 Bloc 管理收藏歌曲狀態
- 使用 `BlocProvider` 注入 `FavoriteSongsCubit` 並調用 `getFavoriteSongs` 方法。
- 使用 `BlocBuilder` 監聽狀態變化，顯示進度條、歌曲列表或錯誤訊息。

## 顯示歌曲資訊
- 使用 `Container` 顯示歌曲圖片，設置圖片大小與圓角。
- 顯示歌曲名稱、藝人名稱及歌曲長度，佈局與播放清單類似。

## 添加和移除收藏歌曲
- 在 `FavoriteSongsCubit` 中創建 `removeSong` 方法移除收藏歌曲並更新狀態。
- 在 UI 中為每首歌曲添加按鈕，點擊後可移除該歌曲並更新 Firestore 資料。
- 使用 `Key` 避免更改其他歌曲的狀態。

## 音樂播放頁面導向
- 在歌曲項目上設置點擊事件，點擊後使用 `Navigator.push` 跳轉到歌曲播放頁面並傳遞歌曲資料。

## 完成專案
- 完成 Spotify 克隆專案，檢查所有功能是否運作正常。
# Terminology
- **Clean Architecture**: 一種將應用程序分為三層（Domain、Data、Presentation）的架構模式，強調分離關注點以提升維護性和擴展性。
- **State Management**: 管理應用程序中狀態變更的方法，以確保資料一致性與視圖同步。
- **BLoC (Business Logic Component)**: 將業務邏輯與 UI 分離，利用資料流來處理事件和狀態更新。
- **Cubit**: BLoC 中一種簡化形式，專注於狀態管理而不處理事件流。
- **Dependency Inversion Principle (DIP)**: 依賴倒置原則，強調高層模組不應依賴低層模組，而應共同依賴抽象。
- **Service Locator Pattern**: 一種設計模式，用於動態解析和提供依賴，簡化物件的管理和取得。
- **GetIt**: Flutter 中的依賴注入框架，用於管理和獲取實例，減少代碼耦合。
- **Dartz**: Dart 的函式式程式庫，用於處理錯誤和函式式數據類型如 `Option` 和 `Either`。
- **Firestore**: Google 的 NoSQL 雲端數據庫，適用於即時資料存取和同步。
- **Firebase Authentication**: Firebase 提供的身份驗證服務，用於實現用戶的身份管理與驗證。
- **Just Audio**: 一個用於播放音頻的 Dart 套件，支援本地和遠端音頻資源。
- **Figma**: UI/UX 設計工具，主要用於設計和分享應用界面和網站。
- **Light Theme**: 使用淺色背景和深色文字的界面主題，用於增強視覺辨識。
- **Dark Theme**: 使用深色背景和淺色文字的界面主題，減少夜間模式下的眼睛疲勞。
- **Presentation Layer**: Clean Architecture 中的一層，負責 UI 和用戶交互。
- **Domain Layer**: Clean Architecture 中的一層，處理業務邏輯和應用核心邏輯。
- **Data Layer**: Clean Architecture 中的一層，管理數據來源和數據存取。
- **ThemeData**: 用於定義 Flutter 應用的主題屬性，如顏色、文字樣式等。
- **Assets Folder**: 專案資源文件夾，包含圖片、字型等資產。
- **SVG (Scalable Vector Graphics)**: 一種基於 XML 的圖形格式，可伸縮和高度精確顯示圖形。
- **Stateless Widget**: 不帶狀態的組件，無法在生命周期中改變其屬性或數據。
- **Stateful Widget**: 帶狀態的組件，允許在生命周期中更新其數據和界面。
- **initState**: 用於初始化狀態的函數，在Stateful Widget創建時執行一次。
- **Future**: 表示可能在未來完成的異步操作的對象。
- **Navigator**: 用於管理應用程式頁面堆疊的工具，實現頁面導航。
- **pushReplacement**: 替換當前頁面並導航到新頁面的Navigator方法。
- **MaterialPageRoute**: 提供基於Material Design的頁面導航路由。
- **Scaffold**: 提供Material Design基本佈局結構的組件。
- **Stack**: 容器組件，用於將子組件按順序堆疊。
- **BoxDecoration**: 用於設置容器的背景、邊框或陰影等裝飾。
- **DecorationImage**: 用於在BoxDecoration中設置背景圖片。
- **Spacer**: 自適應佔位符，用於調整子組件之間的間距。
- **SizedBox**: 設置固定尺寸或空間的組件。
- **Align**: 用於控制子組件在父容器中的對齊方式。
- **TextStyle**: 定義文字樣式的類，如字體大小、顏色和字體粗細。
- **Padding**: 用於設置容器內部內容的邊距。
- **ElevatedButton**: 提供凸起效果的Material Design按鈕組件。
- **styleFrom**: 用於自定義ElevatedButton樣式的輔助方法。
- **Opacity**: 設置組件透明度的屬性或組件。
- **Const Constructor**: 用於創建不可變對象的構造方法，優化效能。
- **Scaffold**：Flutter 中用於構建基礎頁面結構的 widget，提供應用欄、浮動按鈕等基本 UI 元素。
- **Navigator.push**：用於導航至新頁面的 Flutter 方法，將當前頁面推到堆疊的頂部。
- **MaterialPageRoute**：用於定義頁面路由的類別，提供頁面過渡動畫和構造函數。
- **Stack**：Flutter 中的佈局 widget，允許子 widget 層疊顯示。
- **SizedBox**：用於設置固定尺寸或間距的空間 widget。
- **BoxDecoration**：用於定義容器的外觀，例如背景顏色、邊框或陰影的屬性類別。
- **BackdropFilter**：用於對 widget 背景進行模糊處理或其他濾鏡效果的 widget。
- **ClipRRect**：用於對 widget 進行圓角裁剪的 widget。
- **SVG Picture.asset**：用於在 Flutter 中顯示 SVG 圖像的工具，支持矢量圖形渲染。
- **BoxShape.circle**：用於設置 BoxDecoration 的形狀為圓形的屬性。
- **HydratedCubit**：Flutter Bloc 提供的一個擴展類，支持狀態的持久化存儲。
- **ThemeMode**：用於定義應用主題模式的枚舉，包含 light、dark 和 system 模式。
- **MultiblocProvider**：用於注入多個 Cubit 或 Bloc 以供整個應用程序使用的工具。
- **BlocBuilder**：Flutter Bloc 提供的 widget，用於根據狀態變化構建 UI。
- **GestureDetector**：用於檢測點擊、滑動等用戶手勢的 widget。
- **Context.read**：Flutter Bloc 中提供的方法，用於讀取 Bloc 或 Cubit 的實例。
- **emit**：在 Cubit 中用於觸發新狀態更新的方法。
- **PathProvider**：用於獲取文件系統路徑（如應用文檔目錄）的 Flutter 插件。
- **FontWeight.medium**：用於設置文字字重的屬性，表示中等粗細。
- **Hex Color**：用於定義顏色的十六進制格式，例如 `#FFFFFF` 表示白色。
- **FL Block**: 用於管理 Flutter 中狀態的套件，將業務邏輯與 UI 分離，提供更清晰的狀態管理架構。
- **Hydrated Block**: 一種能夠自動將狀態持久化的 FL Block 擴展，方便在應用重啟後恢復狀態。
- **Path Provider**: 用來獲取設備上的目錄路徑，常用於持久化數據存儲。
- **Cubit**: 一種輕量級的狀態管理方式，FL Block 中的基本單位，用來管理單一的狀態。
- **Hydrate Cubit**: 是 Cubit 的一個擴展，提供自動狀態持久化功能，可以保存並恢復先前的狀態。
- **MaterialApp**: Flutter 中用來設置整個應用的主結構和樣式的 widget。
- **MultiBlocProvider**: 用來在 Flutter 應用中提供多個 Bloc 的方法，通常包裹 MaterialApp 來提供 Bloc 設定。
- **BlocBuilder**: 用於構建界面的 Flutter 小部件，根據 Bloc 的狀態變更來刷新 UI。
- **State**: 在 Bloc 中，表示應用或元件的狀態數據，可以是任何類型的資料。
- **Emit**: 在 Bloc 中，表示發送新的狀態以通知界面更新。
- **ThemeMode**: 控制應用界面顯示模式（如黑暗模式或光明模式）的類型。
- **Dark Theme**: 用於顯示深色背景和亮色文字的應用主題。
- **Light Theme**: 用於顯示亮色背景和深色文字的應用主題。
- **GestureDetector**: 用來檢測用戶觸摸手勢（如點擊）的 widget。
- **Context.read**: 在 Bloc 中，用來讀取當前上下文中注入的 Bloc 實例的方法。
- **Constructor**: 用來創建類實例的函數，通常在類的初始化過程中傳遞必要參數。
- **Initial State**: 在 Bloc 或 Cubit 中定義的初始狀態，應用啟動時的默認狀態。
- **Update Theme**: 更改應用主題模式的函數，根據用戶選擇切換光明或黑暗模式。
- **Block Provider**: 提供 Bloc 實例的上下文，讓 Bloc 可以在整個應用中被使用。
- **BlockListener**: 用於監聽 Bloc 狀態改變並做出響應的 widget。
- **Figma**: 一個設計工具，常用於 UI/UX 設計，協助設計師創建界面原型。
- **SVG**: 矢量圖形格式，常用於網頁和應用中顯示高品質圖像，無論放大縮小均不失真。
- **PNG**: 位圖圖像格式，支持透明背景，廣泛應用於網頁和應用程序中。
- **Stateless Widget**: Flutter 中一種無狀態的組件，不會根據用戶交互改變自身狀態，適用於靜態顯示的 UI 元素。
- **Scaffold**: Flutter 中用來構建界面結構的 widget，通常包括 AppBar、Drawer、Body 等部分。
- **Stack**: 用來將多個 widget 層疊顯示的容器，通常與 alignment 配合使用來設置每個 widget 的位置。
- **Alignment**: 設定 widget 在父容器中的位置，通常用於 Stack 或其他容器類型。
- **Column**: 用來將多個子 widget 垂直排列的容器。
- **SizedBox**: 用於設置子 widget 之間的固定空間，常用於調整間距。
- **TextButton**: Flutter 中的一種扁平化按鈕樣式，通常用於輕量級操作。
- **Expanded**: 用來讓子 widget 擴展至父容器的剩餘空間，通常與 Flex 類型的容器（如 Row、Column）配合使用。
- **Padding**: 設置子 widget 與其父容器邊緣之間的空白區域。
- **TextStyle**: 用於定義文本顯示樣式的類型，包含字體、顏色、大小等屬性。
- **Brightness**: 用來指示顯示模式（如暗色模式或亮色模式）的屬性。
- **AppBar**: 頁面頂部的標題欄，通常包括頁面標題和其他操作按鈕。
- **Navigator**: 用來管理頁面導航的 Flutter 類，負責頁面之間的切換和路徑管理。
- **IconButton**: Flutter 中的一種包含圖標的可點擊按鈕，通常用於操作按鈕。
- **Opacity**: 控制 widget 透明度的屬性，用於設置元素的可見度。
- **Theme**: 用來定義應用中全局樣式的設置，包括顏色、字體和顯示模式等。 
- **Extension**: Dart 語言中的擴展，用於為現有類型添加方法或屬性，以提高代碼的可重用性。
- **Scaffold**：Flutter 的一個基本結構元件，用於構建應用的頁面框架，包含 AppBar、Body 等常見佈局。
- **Column**：Flutter 的佈局元件，將子元件以垂直方向排列。
- **Padding**：用於為元件設置內部間距，常用於控制子元件與邊界的距離。
- **InputDecoration**：定義 TextField 的外觀，包括邊框、提示文字等屬性。
- **ThemeData**：用於定義應用的主題樣式，例如顏色、字體、按鈕樣式等。
- **Navigator**：用於在頁面間導航的工具，可推送或彈出頁面路由。
- **MaterialPageRoute**：Flutter 中的一種路由類型，支援 Material Design 樣式的頁面過渡動畫。
- **TextStyle**：用於設置文本的樣式，例如字體大小、顏色和粗細。
- **AppBar**：應用程式的頂部欄，用於顯示標題、按鈕或導航圖標。
- **MainAxisAlignment**：用於控制 Row 或 Column 中子元件的主軸對齊方式。
- **CrossAxisAlignment**：控制 Row 或 Column 中子元件的交叉軸對齊方式。
- **TextField**：用於接受用戶輸入的元件，可設置提示文字、密碼模式等屬性。
- **OutlinedInputBorder**：定義 TextField 的外框樣式，通常用於自訂邊框。
- **GestureDetector**：用於處理手勢事件，例如點擊、拖動和雙擊。
- **StatefulWidget**：Flutter 中的有狀態元件，支援動態更新界面。
- **StatelessWidget**：Flutter 中的無狀態元件，界面是靜態的，不會隨狀態變化。
- **Expanded**：Flutter 的佈局元件，用於在 Row 或 Column 中分配剩餘的空間。
- **Opacity**：用於設置元件的透明度，以控制其顯示效果。
- **SVG Picture**：Flutter 的套件，用於顯示 SVG 格式的矢量圖形。
- **SizedBox**：用於創建具有固定寬高或用於在元件間創建間距的空間元件。
- **Firebase CLI**：Firebase 提供的命令列工具，用於初始化和管理 Firebase 專案及其配置。
- **Standalone Binary**：獨立執行檔形式的 Firebase CLI，無需其他工具即可執行。
- **Pubspec.yaml**：Dart/Flutter 專案的配置檔案，用於管理依賴和專案元數據。
- **InitializeApp**：Firebase 初始化函數，用於在應用啟動時設置 Firebase 配置。
- **Clean Architecture**：軟體開發架構，將系統分為多層（例如 Domain、Data、Presentation），強調分層隔離與依賴方向。
- **Domain Layer**：負責定義業務邏輯和核心實體，與框架和技術無關。
- **Entity**：代表核心業務邏輯中的資料結構，如用戶實體（User Entity）。
- **Repository**：一種抽象層，用於隔離業務邏輯與數據來源的實現。
- **Future**：Dart 中表示異步操作結果的類型，用於處理非同步方法。
- **Firebase Authentication**：Firebase 提供的身份驗證服務，用於用戶註冊和登錄。
- **Create User With Email And Password**：Firebase Authentication 提供的 API，用於通過電子郵件和密碼創建新用戶。
- **Try-Catch**：Dart 中的異常處理機制，用於捕獲和處理執行過程中的錯誤。
- **Dependency Inversion Principle (DIP)**：設計原則，強調高層模組不應依賴低層模組，而是依賴抽象。
- **Get It**：Flutter/Dart 的依賴注入工具，用於管理依賴的實例化和生命周期。
- **Service Locator**：一種依賴管理模式，通過集中註冊和查詢來管理對象實例。
- **Register Singleton**：在 Get It 中註冊單例類型的方式，確保應用中只創建一個實例。
- **Abstract Class**：一種僅定義方法和屬性的介面，具體邏輯需由其子類實現。
- **Json Serialization**：將物件轉換為 JSON 格式，或將 JSON 格式轉換為物件的過程。
- **Create User Request**：一種數據模型，封裝用戶註冊所需的資料，例如電子郵件、密碼和全名。
- **SL (Service Locator)**：用於標識和訪問依賴的全局實例變數，在整個專案中共享。
- **抽象類別**：用於定義基礎行為的類別，無法直接實例化，需由子類實現具體方法。
- **泛型參數**：允許類別或方法在聲明時指定具體的資料類型，提供靈活性與類型安全性。
- **呼叫方法**：類別中的特殊函式，實現具體邏輯，供其他代碼調用。
- **回傳類型**：方法的輸出類型，定義該方法預期返回的資料型態。
- **右側**：`Either`資料結構中表示成功的結果。
- **左側**：`Either`資料結構中表示失敗的結果。
- **服務定位器**：一種設計模式，用於集中管理依賴項並簡化依賴注入。
- **資料層**：應用程式的底層結構，負責數據的存取與操作。
- **域層**：處理業務邏輯的層級，位於資料層與表現層之間。
- **表現層**：應用程式的用戶界面，直接與使用者互動。
- **Firebase 認證**：Google 提供的身份驗證服務，支援多種登入方式。
- **狀態管理**：應用程式中處理資料與狀態變化的機制。
- **Navigator**：Flutter 提供的路由工具，用於管理頁面導航與歷史記錄。
- **MaterialPageRoute**：Flutter 中的一種路由，用於管理頁面過渡效果。
- **Scaffold**：Flutter 中的基礎佈局工具，提供標準化的界面結構。
- **Snackbar**：用於短暫顯示訊息的彈出式元件，通常用於通知或提示。
- **異常處理**：程序運行中對錯誤情況的捕獲與處理機制。
- **控制器**：Flutter 中的物件，用於監視與控制輸入框的內容。
- **try-catch**：用於捕獲程式執行期間可能出現的異常，並進行處理。
- **removeUntil**：Navigator 方法，用於清空路由堆疊並導航到指定頁面。
- **抽象類別 (Abstract Class)**：定義方法結構但不實作的類別，必須由子類別實作具體功能。
- **泛型 (Generics)**：提供類別或方法參數化的能力，以提升程式碼的靈活性與重用性。
- **服務定位器 (Service Locator)**：一種設計模式，集中管理與提供依賴項的實例。
- **依賴注入 (Dependency Injection)**：將物件的依賴從外部注入，提升模組化與可測試性。
- **Firebase 認證 (Firebase Authentication)**：提供多種方式進行用戶驗證的服務，例如電子郵件、密碼、Google 登入等。
- **Firebase 存儲 (Firebase Storage)**：用於存儲文件、圖片、音樂等檔案的雲存儲服務。
- **Firestore 資料庫 (Cloud Firestore)**：雲端 NoSQL 資料庫，支持即時同步與查詢。
- **文件集合 (Collection)**：Firestore 中用於分組和管理文件的結構，類似於資料庫的表。
- **文件 (Document)**：Firestore 中的基本資料單元，包含鍵值對結構的資料。
- **自動生成 ID (Auto ID)**：Firestore 提供的功能，為文件生成唯一標識符。
- **異常處理 (Exception Handling)**：處理程式運行中可能出現的錯誤或異常情況的機制。
- **回傳類型 (Return Type)**：方法或函式返回的值的資料型別。
- **JSON 格式 (JSON Format)**：用於資料交換的輕量級格式，結構為鍵值對。
- **單一子滾動視圖 (SingleChildScrollView)**：Flutter 中用於在空間不足時滾動顯示內容的 widget。
- **頁面導航 (Page Navigation)**：應用中切換頁面的過程，常使用 Navigator 來實現。
- **SnackBar**：Flutter 提供的一種 UI 元件，用於在畫面下方短暫顯示提示訊息。
- **右值 (Right)**：Either 類中的成功結果，用於表示操作成功的輸出。
- **左值 (Left)**：Either 類中的錯誤結果，用於表示操作失敗的原因或訊息。
- **請求認證 (Request Authentication)**：檢查用戶是否通過身份驗證的過程，確保數據操作的安全性。
- **規則編輯 (Rules Editing)**：設置 Firestore 或 Storage 的讀寫權限的操作，確保資料的安全性和可用性。
- 專案文件夾：存放專案相關資源和程式碼的結構化目錄。
- 資產目錄：專門存放圖片、向量、字型等應用所需的靜態資源的文件夾。
- 向量圖：通常為 SVG 格式的圖片，具有可縮放性且不會失真。
- PNG 格式：一種無損壓縮的點陣圖格式，適用於圖片資產。
- 頂層卡片：首頁中的主要設計元素，用於展示關鍵內容或圖片的元件。
- AppBar：應用程式頂部的導航欄，用於顯示標題、按鈕等內容。
- 頂層導覽頁：應用的主要頁面，例如首頁、使用者頁面等。
- Stateless Widget：無狀態元件，適用於靜態不變的 UI 元素。
- Stateful Widget：有狀態元件，適用於需要更新或互動的 UI 元素。
- 單一滾動視圖：允許單方向滾動的視圖元件。
- 堆疊：一種容器元件，允許子元件重疊排列。
- 靜態常數：用於存放不變的值，例如資源路徑或顏色代碼的變數。
- 頂部卡片：用於首頁的主視覺元件，顯示背景圖片或相關資訊。
- 對齊屬性：設定元件的相對位置，例如左對齊、居中或底部對齊。
- Padding：設定元件內部的邊距，用於調整元件的顯示間距。
- 標籤顏色：設定標籤文字在不同模式下的顏色，例如深色模式或亮色模式。
- 頂部控制器：用於管理 TabBar 或類似元件的控制器。
- 單一狀態混合：讓元件支援單一狀態的生命週期混合模式。
- 主色：應用程式中主要使用的顏色，用於保持一致的視覺風格。
- 字型大小：設定文字的顯示大小，以適應不同的設計需求。
- 乾淨架構：一種分層架構設計，將應用分為資料層、領域層和展示層。
- 實體：領域層中用於描述核心業務邏輯和資料的物件。
- 模型：資料層中用於表示與資料來源交互的資料結構。
- JSON：一種輕量級的資料交換格式，用於在前後端間傳遞資料。
- Firestore：Google 提供的雲端 NoSQL 資料庫服務，適合實時同步應用。
- 時間戳：用於記錄特定時間的標準格式資料類型。
- 抽象類別：未實現具體方法的類別，用於定義通用的介面或契約。
- 資料夾結構：將專案中不同責任的檔案組織到相關的資料夾中。
- 依賴反轉原則：設計模式，確保高階模組不依賴低階模組，兩者皆依賴於抽象。
- Either：一種用於封裝結果和錯誤的資料結構，可用於錯誤處理。
- 查詢快照：Firestore 中查詢的結果物件，包含資料集合的多個文件。
- 映射方法：將 JSON 資料轉換為 Dart 物件的過程，例如 fromJson 方法。
- 擴展方法：為現有類別添加功能的方法，通常用於轉換資料類型。
- 使用案例：描述特定業務操作邏輯的類別，負責調用領域層的服務。
- 服務定位器：一種依賴注入模式，用於管理和提供應用所需的實例。
- 異步操作：非同步執行的程式邏輯，例如讀取遠端資料庫。
- Try-Catch：用於捕捉和處理程式執行期間可能出現的異常的結構。
- 權重：在 Firebase 中使用 orderBy 進行排序時，用於指定排序的欄位。
- 限制：查詢時指定返回結果的數量，例如限制為最近三筆資料。
- 錯誤訊息：當操作失敗時向使用者回報的錯誤描述，提升使用體驗。
- 狀態管理（State Management）：用於管理應用中狀態和其變化的技術，例如 Bloc。
- Bloc（Business Logic Component）：Dart 中的一個模式，分離業務邏輯與 UI 代碼。
- Cubit：Bloc 的簡化版本，僅負責處理狀態和其變更。
- BlocBuilder：Bloc 狀態的監聽器，用於在狀態變化時重新構建 UI。
- 狀態（State）：應用中當前的資料和 UI 狀態，例如 Loading、Loaded 和 Failure。
- ListView：Flutter 中用於顯示可滾動列表的組件。
- 橫向滾動（Horizontal Scroll）：ListView 的一種滾動方向設置，適合顯示橫向資料。
- BlocProvider：Bloc 的提供器，用於將 Bloc 注入到小部件樹中。
- TapBarView：一種在 Flutter 中實現頁籤切換內容的組件。
- 圖片裝飾（BoxDecoration）：用於設置小部件背景或邊框的裝飾。
- 網路圖片（NetworkImage）：從 URL 加載的圖片，通常用於展示遠端資源。
- Expanded：Flutter 中的佈局組件，用於擴展子組件以填充剩餘空間。
- 圓角邊框（BorderRadius.circular）：設置小部件邊框的圓角半徑。
- 大小框（SizedBox）：Flutter 中用於設置固定大小的空間或間距。
- 語義分離（SeparatedBuilder）：ListView 的生成方法，用於分隔子項目。
- 圖標（Icon）：用於顯示小的圖片或圖形符號，例如播放按鈕圖標。
- 主題檢查（isDarkMode）：檢查當前應用主題模式是否為深色模式。
- Transformation（Matrix4）：用於移動、縮放或旋轉小部件的屬性。
- 子部件對齊（Alignment）：設置小部件內的內容位置，例如底部右對齊（BottomRight）。
- 狀態管理（State Management）：用於管理應用中狀態和其變化的技術，例如 Bloc。
- Bloc（Business Logic Component）：Dart 中的一個模式，分離業務邏輯與 UI 代碼。
- Cubit：Bloc 的簡化版本，僅負責處理狀態和其變更。
- BlocBuilder：Bloc 狀態的監聽器，用於在狀態變化時重新構建 UI。
- 狀態（State）：應用中當前的資料和 UI 狀態，例如 Loading、Loaded 和 Failure。
- ListView：Flutter 中用於顯示可滾動列表的組件。
- 橫向滾動（Horizontal Scroll）：ListView 的一種滾動方向設置，適合顯示橫向資料。
- BlocProvider：Bloc 的提供器，用於將 Bloc 注入到小部件樹中。
- TapBarView：一種在 Flutter 中實現頁籤切換內容的組件。
- 圖片裝飾（BoxDecoration）：用於設置小部件背景或邊框的裝飾。
- 網路圖片（NetworkImage）：從 URL 加載的圖片，通常用於展示遠端資源。
- Expanded：Flutter 中的佈局組件，用於擴展子組件以填充剩餘空間。
- 圓角邊框（BorderRadius.circular）：設置小部件邊框的圓角半徑。
- 大小框（SizedBox）：Flutter 中用於設置固定大小的空間或間距。
- 語義分離（SeparatedBuilder）：ListView 的生成方法，用於分隔子項目。
- 圖標（Icon）：用於顯示小的圖片或圖形符號，例如播放按鈕圖標。
- 主題檢查（isDarkMode）：檢查當前應用主題模式是否為深色模式。
- Transformation（Matrix4）：用於移動、縮放或旋轉小部件的屬性。
- 子部件對齊（Alignment）：設置小部件內的內容位置，例如底部右對齊（BottomRight）。
- **Stateless Widget**：Flutter 中一種無狀態的 widget，內容固定，不會因用戶操作而改變。
- **Scaffold**：Flutter 提供的基本頁面結構，包含 AppBar、Body、FloatingActionButton 等常見元素。
- **GestureDetector**：一個偵測用戶手勢（如點擊、滑動）的 widget，用於添加互動功能。
- **Navigator**：用於管理頁面導航的 Flutter 組件，提供 push 和 pop 方法實現頁面跳轉。
- **MaterialPageRoute**：一種路由類型，提供 Material Design 樣式的頁面轉場效果。
- **AppBar**：Scaffold 中的標準應用欄，用於顯示標題和操作按鈕。
- **IconButton**：一個包含圖標且支持點擊事件的按鈕 widget。
- **NetworkImage**：用於從網絡加載圖片的類，適合動態顯示遠端圖片資源。
- **SingleChildScrollView**：一種支持滾動的 widget，適用於子內容可能超出屏幕的情況。
- **Column**：一種將子 widget 垂直排列的布局組件。
- **Padding**：用於設置 widget 周圍內邊距的 widget。
- **BorderRadius**：用於設置邊框的圓角屬性，通常搭配 BoxDecoration 使用。
- **BoxDecoration**：用於裝飾 container，例如設置背景色、圖片或圓角等樣式的類。
- **TextStyle**：用於設置文字樣式的類，包括字體大小、顏色、粗細等屬性。
- **MainAxisAlignment**：控制主軸（如 Column 的垂直軸）上子 widget 的排列方式的屬性。
- **OutlineButton**：Flutter 中一種邊框按鈕樣式，適用於低優先級操作（現已棄用，建議用 OutlinedButton）。
- **Icon**：用於顯示 Material Design 圖標的 widget。
- **setState**：Flutter 中的一個方法，用於觸發狀態改變並重新構建 UI（僅限 Stateful Widget 使用）。
- **Container**：一種多功能的 widget，用於設置大小、邊距、背景等樣式的容器。
- **ActionBar**：通常指 AppBar 的右側操作區域，可用於放置按鈕或功能圖標。
- **Slider**：一個允許用戶調整值（例如進度條）的 widget，適合用於音樂播放進度控制。
- **Cubit**：Flutter 中輕量級的狀態管理工具，基於 Bloc 提供簡化的狀態處理方式。
- **Stream**：Dart 中的數據流，用於監聽事件並響應，例如音樂的播放進度更新。
- **AudioPlayer**：Just Audio 套件中的類，用於處理音頻播放、暫停、停止等功能。
- **Duration**：Dart 標準庫中的類，表示時間間隔，用於處理音樂的時長與進度。
- **listen**：Stream 中的一個方法，用於訂閱事件並執行回調函數以更新 UI 或數據。
- **BlockProvider**：Flutter Bloc 提供的一個 widget，用於將 Cubit 或 Bloc 注入到 widget 樹中。
- **BlockBuilder**：一個基於狀態變化來構建 UI 的 Bloc 工具，適合響應式設計。
- **CircularProgressIndicator**：Flutter 中的圓形進度指示器，用於顯示加載狀態。
- **min/max**：Slider 的屬性，用於設置最小值和最大值，控制滑塊的範圍。
- **setShape**：BoxDecoration 的屬性，用於設置形狀，例如圓形或矩形。
- **BoxShape.circle**：Flutter 提供的形狀類型，表示圓形，適用於按鈕設計。
- **GestureDetector**：用於檢測觸摸手勢的 widget，例如點擊、滑動等。
- **play/pause**：音頻播放的常見功能，控制音樂的開始與暫停。
- **format**：將數據轉換為特定顯示格式的操作，例如將時間轉換為「分鐘：秒」。
- **AppColors.primary**：一個應用主題顏色的變量，通常用於統一設計風格。
- **emit**：Cubit 的方法，用於向 UI 傳遞新的狀態更新。
- **try/catch**：Dart 中的錯誤處理機制，用於捕獲和處理異常情況。
- **dispose**：用於釋放資源或清理數據的方法，避免內存洩漏。
- **Context.read**：Bloc 提供的方法，用於訪問注入的 Cubit 或 Bloc 並獲取其數據。
- **Firebase Authentication**：提供用戶身份驗證功能，支持多種登入方式如郵件、Google、Facebook 等。
- **Firestore**：Firebase 的雲端 NoSQL 資料庫，用於存儲結構化數據，支持實時同步功能。
- **Collection**：Firestore 中的一組文件集合，類似資料表的概念。
- **Document**：Firestore 中的資料單元，存儲具體的鍵值對，類似資料表中的一列資料。
- **Subcollection**：Firestore 文件中的嵌套集合，用於組織更複雜的數據結構。
- **Doc Method**：Firestore 的方法，用於創建或操作具有特定 ID 的文件。
- **Set Method**：Firestore 中的 API，用於以指定 ID 創建或覆寫文件。
- **Add Method**：Firestore 中的 API，用於新增文件並自動生成文件 ID。
- **Query Snapshot**：Firestore 查詢的結果集合，包含一組文件的快照。
- **Where Clause**：Firestore 的查詢條件，用於篩選符合特定條件的文件。
- **Try-Catch Block**：程式語言中的結構，用於捕捉和處理可能發生的異常錯誤。
- **Boolean**：布林型別，表示邏輯值（真或假）。
- **Cubit**：Flutter Bloc 架構的一部分，用於管理應用的狀態。
- **Service Locator**：設計模式，用於集中管理服務實例的創建和訪問。
- **Use Case**：應用程式中的業務邏輯單位，封裝特定功能的實現。
- **Entity**：數據模型的定義，用於描述業務邏輯中的核心數據結構。
- **Model**：與資料存儲交互的資料結構，通常映射到資料庫中的數據格式。
- **Favorite Button**：UI 元件，用於標記歌曲是否被加入收藏。
- **Stateless Widget**：Flutter 中不需要管理狀態的 UI 組件類型。
- **Bloc Builder**：Flutter Bloc 的組件，用於監聽和重建基於 Cubit 或 Bloc 的狀態變化。
- **Stateless Widget**：一種無狀態的 Flutter 小部件，用於構建不依賴可變數據的介面。
- **AppBar**：Flutter 提供的標題欄組件，通常用於顯示標題、操作按鈕等。
- **Navigator**：Flutter 的路由管理工具，用於頁面導航和路由操作。
- **IconButton**：一個帶有圖示的按鈕，用於執行特定的操作。
- **Column**：Flutter 的佈局小部件，用於將子項垂直排列。
- **Container**：Flutter 的基礎組件，可用於佈局、裝飾和尺寸調整。
- **BoxDecoration**：用於裝飾容器的類，可設置背景色、圓角等樣式。
- **Figma**：一款用於設計和原型製作的協作工具。
- **Firebase Authentication**：提供用戶身份驗證功能的 Firebase 服務。
- **Firestore**：Firebase 提供的雲端 NoSQL 資料庫服務。
- **DocumentSnapshot**：從 Firestore 中讀取的單筆文件數據的快照。
- **Entity**：程式中的核心業務邏輯對象，通常用於封裝數據。
- **Model**：程式中用於處理數據的物件，包含與資料來源交互的邏輯。
- **toJson**：將物件轉換為 JSON 格式的函式，便於傳輸和存儲。
- **fromJson**：從 JSON 格式數據建立物件的函式，便於數據解析。
- **URL**：統一資源定位符，用於指定網絡資源的位置。
- **Either**：一種函數式程式設計中表示可能成功或失敗的數據結構。
- **Future**：Dart 的異步操作類型，用於處理非同步任務。
- **Try-Catch**：用於捕獲和處理程式異常的結構化方式。
- **Default Image**：用於替代缺失圖像的一種預設圖像資源。
- **Use Case**：軟體設計中的業務邏輯單元，用於執行特定操作或用例。
- **BLoC (Business Logic Component)**：Flutter 中的狀態管理工具，將業務邏輯與 UI 分離。
- **Cubit**：BLoC 的簡化版本，用於管理單一狀態流的邏輯。
- **State Management**：應用程式中用於跟蹤 UI 狀態的技術，確保資料和介面一致性。
- **Abstract Class**：一種無法直接實例化的類，通常用於定義行為介面。
- **Profile Info Loading**：用於表示用戶資訊正在加載的狀態。
- **Profile Info Loaded**：用於表示用戶資訊已成功加載的狀態，並攜帶用戶實體數據。
- **Profile Info Failure**：用於表示用戶資訊加載失敗的狀態，通常包含錯誤訊息。
- **Use Case**：代表應用特定功能的邏輯單元，實現業務規則。
- **Either**：一種數據結構，用於表示成功（右側）或失敗（左側）的結果。
- **Fold Method**：操作 Either 結構，分別處理成功與失敗的邏輯分支。
- **BLoC Provider**：用於將 BLoC 實例注入到子樹的 Flutter 組件。
- **BLoC Builder**：用於在狀態更改時重新構建 UI 的 Flutter 組件。
- **CircularProgressIndicator**：一個 Flutter 組件，用於顯示正在進行的操作。
- **BoxDecoration**：定義容器的裝飾，包括顏色、圖片和形狀等。
- **NetworkImage**：Flutter 中用於從網路加載圖像的工具類。
- **Firestore Collection**：Firebase Firestore 的資料結構，用於存儲和組織文檔。
- **fromJson Method**：將 JSON 數據轉換為物件實例的函式。
- **Repository Pattern**：一種設計模式，用於抽象化數據訪問層。
- **Service Locator**：一種用於管理和提供服務或依賴項的設計模式。
- **Song Model**：代表歌曲數據的物件模型，包含相關屬性和方法。
- **Song Entity**：表示業務層級的歌曲對象，通常用於介面或業務邏輯中。
- **Bloc (Business Logic Component)**：一種在 Flutter 中管理應用程式狀態的架構，將商業邏輯與 UI 分離。
- **Cubit**：一種簡化的 Bloc，適用於簡單的狀態管理，通常用於單一狀態的管理。
- **State Management**：一種處理應用程式狀態的技術，保證 UI 與資料的一致性。
- **Abstract Class**：定義方法但不實作的類別，用於規範子類別的行為。
- **Favorite Songs Loading**：用來表示用戶的最愛歌曲正在加載的狀態。
- **Favorite Songs Loaded**：用來表示最愛歌曲已加載的狀態，並攜帶歌曲數據。
- **Favorite Songs Failure**：用來表示最愛歌曲加載失敗的狀態，通常會顯示錯誤訊息。
- **Use Case**：應用中的具體功能單位，處理業務邏輯並返回結果。
- **Bloc Provider**：一個將 Bloc 實例提供給子樹的 Widget，使得 Bloc 可以在 Widget 樹中共享。
- **Bloc Builder**：監聽 Bloc 狀態改變並更新 UI 的 Widget。
- **CircularProgressIndicator**：顯示正在處理的圓形進度條。
- **Padding**：用於增加內邊距，讓 Widget 不會緊貼其父容器的邊界。
- **NetworkImage**：從網路加載圖像的 Flutter Widget，常用於顯示遠端圖片。
- **BoxDecoration**：為容器提供裝飾，包括顏色、邊框、陰影等樣式。
- **Navigator Push**：用於在 Flutter 中執行頁面跳轉。
- **Key**：用於在 Widget 樹中識別 Widget 的唯一標識符，有助於提高性能並避免重建不必要的部分。
- **MaterialPageRoute**：Flutter 中的一種頁面路由，用於簡單的頁面轉換。
- **ListView**：顯示可滾動的項目列表，常用於顯示長列表數據。
- **SizedBox**：用於設置固定大小的空間，可以用來調整 UI 的間距。
- **GestureDetector**：用於檢測用戶手勢（如點擊、拖動等）的 Widget，通常與事件處理相關聯。
- **FireStore**：Firebase 提供的 NoSQL 資料庫服務，用於存儲和同步數據。