Tangyuan/gradle/libs.versions.toml
grtsinry43 46588259dd
feat: Implement user profile screen and enhance authentication
This commit introduces a dedicated user profile screen (`UserScreen`) and significantly enhances the authentication system by adding registration, auto-login, and robust form validation.

**Key Changes:**

*   **feat(UserScreen):**
    *   Added a new `UserScreen` to display the logged-in user's profile.
    *   Displays user details including avatar, nickname, ID, bio, location, and email in a styled card.
    *   Includes a menu section for actions like "Post Management," "Settings," and "About."
    *   Shows a "not logged in" state to prompt users to log in.

*   **feat(Auth):**
    *   **Registration:** Implemented a registration flow alongside the login flow on the `LoginScreen`. Users can now switch between Login and Register modes.
    *   **Auto-Login:** The app now automatically logs in the user on startup if a valid token or saved credentials exist, improving user experience.
    *   **Token Management:** Enhanced `TokenManager` to handle JWT parsing to extract `userId`, check token validity (expiration), and securely store credentials. Added `java-jwt` dependency for this.
    *   **Logout:** Improved the logout function to clear all stored tokens and user credentials from `SharedPreferences`.

*   **feat(Validation):**
    *   Introduced `ValidationUtils` to provide real-time validation for phone number, password, and nickname fields on the `LoginScreen`.
    *   Input fields now display specific error messages to guide the user (e.g., "Password must contain a letter," "Invalid phone number format").

*   **refactor(LoginScreen):**
    *   Redesigned the `LoginScreen` to support both login and registration (`AuthMode`) with animated transitions between modes and form fields.
    *   Form submission buttons are dynamically enabled based on validation results.
    *   After successful registration, the user is now automatically logged in.

*   **refactor(UserViewModel):**
    *   Integrated auto-login logic (`checkAutoLogin`) that runs on initialization.
    *   Refactored `login` and `register` flows to handle token storage and fetch user profile data immediately after authentication.
    *   Added `isLoggedIn()` to provide a reliable check of the current authentication state.

*   **refactor(TopBar):**
    *   The top bar avatar now correctly reflects the user's login state. It displays the user's avatar when logged in and a generic app icon when logged out.
    *   Clicking the avatar/icon now navigates to the `UserScreen` if logged in, or the `LoginScreen` if not.
2025-10-07 00:06:37 +08:00

72 lines
4.4 KiB
TOML

[versions]
agp = "8.12.3"
coilCompose = "2.7.0"
javaJwt = "4.5.0"
kotlin = "2.2.20"
coreKtx = "1.17.0"
junit = "4.13.2"
junitVersion = "1.3.0"
espressoCore = "3.7.0"
lifecycleRuntimeKtx = "2.9.4"
activityCompose = "1.11.0"
composeBom = "2025.09.01"
materialIconsCore = "1.7.8"
panguJvm = "0.2.0"
retrofit = "3.0.0"
okhttp = "4.12.0"
gson = "2.13.2"
securityCrypto = "1.1.0"
datastore = "1.1.7"
hilt = "2.57.2"
hiltNavigationCompose = "1.3.0"
navigationCompose = "2.9.5"
uiGraphics = "1.9.2"
animationCore = "1.9.2"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
androidx-material-icons-core = { module = "androidx.compose.material:material-icons-core", version.ref = "materialIconsCore" }
androidx-material-icons-extended = { module = "androidx.compose.material:material-icons-extended", version.ref = "materialIconsCore" }
coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coilCompose" }
java-jwt = { module = "com.auth0:java-jwt", version.ref = "javaJwt" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
pangu-jvm = { module = "io.github.darkokoa:pangu-jvm", version.ref = "panguJvm" }
retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" }
retrofit-converter-gson = { group = "com.squareup.retrofit2", name = "converter-gson", version.ref = "retrofit" }
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" }
okhttp-logging-interceptor = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp" }
gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" }
androidx-security-crypto = { group = "androidx.security", name = "security-crypto", version.ref = "securityCrypto" }
androidx-datastore-preferences = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "datastore" }
# Hilt dependencies
hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" }
hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hilt" }
androidx-hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "hiltNavigationCompose" }
# ViewModel dependencies
androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "lifecycleRuntimeKtx" }
androidx-lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycleRuntimeKtx" }
ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics", version.ref = "uiGraphics" }
androidx-animation-core = { group = "androidx.compose.animation", name = "animation-core", version.ref = "animationCore" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" }