diff --git a/README.md b/README.md
index 2965c17..eefaf6a 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,11 @@
# HFUT-Schedule(聚在工大)
+
-[
![](https://f-droid.org/badge/get-it-on-zh-cn.png)
](https://f-droid.org/packages/com.hfut.schedule)
+[![GitHub](https://img.shields.io/github/v/release/Chiu-xaH/HFUT-Schedule?logo=github&label=GitHub&style=for-the-badge)](https://github.com/Chiu-xaH/HFUT-Schedule/releases/latest)
+[![F-Droid](https://img.shields.io/f-droid/v/com.hfut.schedule?logo=fdroid&style=for-the-badge)](https://f-droid.org/packages/com.hfut.schedule)
+[![F-Droid](https://img.shields.io/github/v/release/Chiu-xaH/HFUT-Schedule?logo=gitee&label=Gitee&style=for-the-badge)](https://gitee.com/chiu-xah/HFUT-Schedule/releases/tag/Android)
+
+
## 说明:
作为本校23届学生,初到学校时了解到大家常用的可以查看课表、成绩、考试等信息的是若干微信小程序和网页,平台较多较分散,且冷启动加载速度较慢,功能较少,多数接口失效,使用起来感觉不便,恰本人那时刚学安卓开发,为解决痛点,并作为实战项目,本应用就诞生了,面向宣区校内同学(理论上合肥校区也可用)使用,更快的启动速度、更全面的功能、无广告设计
@@ -16,27 +19,21 @@ height="80">](https://f-droid.org/packages/com.hfut.schedule)
![导图](/img/mindMaster.png)
## 权限:
-1.日历(将事项作为日程写入日历)
-
-2.存储(导入导出课程表文件)
-
-3.相机(洗浴扫码)
+网络、日历(将聚焦事项作为日程写入日历)、存储(导入导出课程表文件)、相机(洗浴扫码)
## 使用:
### 环境要求
ARM架构,支持64 Bit软件、搭载Android 7.0 (SDK 26)及以上版本的设备,初次使用要接入互联网
### 初次使用
-下载好APK安装包后,进行安装,保证接入互联网的环境下,填入学号与信息门户密码,点击登录,等待加载完毕即可使用。(最好留在课表页面等待加载完毕,因为要后台登录3个平台,有两个Toast弹完后即完全登录,友友们能不能稍作等待,登陆这一次以后几十天就不用了...)
+从开头三个徽章之一下载好APK后,进行安装,保证接入互联网的环境下,填入学号与信息门户密码,点击登录,等待加载完毕即可使用。(最好留在课表页面等待加载完毕,因为要后台登录3个平台,有两个Toast弹完后即完全登录...)
### 后续使用
-完全登陆后获取所需的数据,会自动进行本地缓存,以后可随便断网看课表,登陆一次教务系统有效期只有3小时,另外两个平台(一卡通和智慧社区)有效期有足足几十天,不需要同学们经常登录刷新哈,关于更多细分说明在APP中子功能界面右上角会有说明按钮,点击可查看,有不懂的或者有Bug提交issue或发邮件
+完全登陆后会获取所需的数据,自动缓存,以后可随便断网看课表,登陆一次教务系统有效期只有3小时,另外两个平台(一卡通和智慧社区)有效期有几十天,不需要同学们经常登录刷新,关于更多细分说明在APP中子功能界面右上角会有说明按钮,点击可查看
### 软件升级
如有更新,会在首页底栏【选项】显示小红点,点击此Tab,在选项界面会有标红卡片,提示新版本,点击下方请求更新,等待进度条即可
-已上架到F-Droid
-
## [接口文档](markdown/API.md)
供校内学生们方便参考或学习
@@ -56,20 +53,26 @@ UI设计 Material You (Material Design 3)
[Retrofit](https://github.com/square/retrofit) 网络请求
-[Gson](https://github.com/google/gson) JSON处理
+[Gson](https://github.com/google/gson) JSON解析
-[Haze](https://github.com/chrisbanes/haze) 实时模糊
+[Jsoup](https://github.com/jhy/jsoup) XML/HTML解析
-[Accompanist](https://github.com/google/accompanist) 透明状态栏
+[Zxing](https://github.com/zxing/zxing) 二维码
-[Monet](https://github.com/Kyant0/Monet) 莫奈取色(供SDK不支持M3取色平替)
+[Haze](https://github.com/chrisbanes/haze) 实时模糊(SDK>=33)
-[Dagger](https://github.com/google/dagger) Hilt注入
+[Accompanist](https://github.com/google/accompanist) 用做实现透明状态栏
-[Glide](https://github.com/bumptech/glide) 图片
+[Monet](https://github.com/Kyant0/Monet) 莫奈取色(供SDK<32不支持MY取色平替)
+
+[Dagger](https://github.com/google/dagger) Hilt注入,辅助莫奈取色功能
+
+[Glide](https://github.com/bumptech/glide) 网络图片
[EdDSA Java](https://github.com/str4d/ed25519-java) 加密(供和风天气API使用)
+[Konfetti](https://github.com/DanielMartinus/Konfetti) 礼花🎉动画
+
## [更新日志](markdown/UPDATE.md)
## 统计
diff --git a/app/build.gradle b/app/build.gradle
index 1ee11a1..6fee81c 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -23,8 +23,8 @@ android {
applicationId "com.hfut.schedule"
minSdk 26
targetSdk 33
- versionCode 156
- versionName "4.13.4.1"
+ versionCode 157
+ versionName "4.13.4.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary true
@@ -145,6 +145,8 @@ dependencies {
//implementation "androidx.biometric:biometric:1.1.0"
//用于和风天气密钥生成的JWT
implementation 'net.i2p.crypto:eddsa:0.3.0'
+ //礼花
+ implementation 'nl.dionsegijn:konfetti-compose:2.0.5'
//Fragment
// implementation "androidx.fragment:fragment-ktx:1.8.5"
}
diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json
index 2daaedd..2c98324 100644
--- a/app/release/output-metadata.json
+++ b/app/release/output-metadata.json
@@ -11,8 +11,8 @@
"type": "SINGLE",
"filters": [],
"attributes": [],
- "versionCode": 156,
- "versionName": "4.13.4.1",
+ "versionCode": 157,
+ "versionName": "4.13.4.2",
"outputFile": "app-release.apk"
}
],
diff --git a/app/src/main/java/com/hfut/schedule/activity/main/LoginActivity.kt b/app/src/main/java/com/hfut/schedule/activity/main/LoginActivity.kt
index 015dd02..b0e921a 100644
--- a/app/src/main/java/com/hfut/schedule/activity/main/LoginActivity.kt
+++ b/app/src/main/java/com/hfut/schedule/activity/main/LoginActivity.kt
@@ -7,16 +7,33 @@ import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.widget.Toast
+import androidx.compose.animation.core.tween
+import androidx.compose.animation.expandVertically
+import androidx.compose.animation.scaleIn
+import androidx.compose.animation.scaleOut
+import androidx.compose.animation.shrinkVertically
+import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
import androidx.lifecycle.lifecycleScope
+import androidx.navigation.compose.NavHost
+import androidx.navigation.compose.composable
+import androidx.navigation.compose.rememberNavController
import com.hfut.schedule.logic.utils.PermissionManager.checkAndRequestStoragePermission
import com.hfut.schedule.logic.utils.SharePrefs
import com.hfut.schedule.logic.utils.SharePrefs.prefs
+import com.hfut.schedule.logic.utils.getCelebration
import com.hfut.schedule.ui.activity.home.main.saved.Add
import com.hfut.schedule.ui.activity.home.main.saved.NoNetWork
import com.hfut.schedule.ui.activity.home.main.saved.getNum
+import com.hfut.schedule.ui.activity.login.First
+//import com.hfut.schedule.ui.activity.login.FirstUI
import com.hfut.schedule.ui.activity.login.LoginUI
+import com.hfut.schedule.ui.activity.login.UseAgreementUI
+import com.hfut.schedule.ui.utils.NavigateManager
+import com.hfut.schedule.ui.utils.NavigateManager.ANIMATION_SPEED
import com.hfut.schedule.ui.utils.components.MyToast
+import com.hfut.schedule.ui.utils.components.PartyAnimation
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
@@ -31,11 +48,37 @@ class LoginActivity : BaseActivity() {
val switchUpload = prefs.getBoolean("SWITCHUPLOAD",true )
var value = 0
+ @SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
@Composable
override fun UI() {
- if(startAcitivity && intent.getBooleanExtra("nologin",true)) {
- NoNetWork(super.networkVm,super.loginVm,super.uiVm)
- } else LoginUI(super.loginVm)
+ val navController = rememberNavController()
+ val first = if(prefs.getBoolean("canUse",false)) First.HOME.name else First.USE_AGREEMENT.name
+ NavHost(
+ navController = navController,
+ startDestination = first,
+ enterTransition = {
+ NavigateManager.fadeAnimation.enter
+ },
+ exitTransition = {
+ NavigateManager.fadeAnimation.exit
+ }
+ ) {
+ composable(First.HOME.name) {
+ // 如果庆祝为true则庆祝
+ val time = if(getCelebration()) 1L else 0L
+ PartyAnimation(timeSecond = time) {
+ if(startAcitivity && intent.getBooleanExtra("nologin",true)) {
+ NoNetWork(super.networkVm,super.loginVm,super.uiVm)
+ } else LoginUI(super.loginVm)
+ }
+ }
+ composable(First.USE_AGREEMENT.name) {
+ PartyAnimation {
+ UseAgreementUI(navController)
+ }
+ }
+ }
+
}
//打开方式txt
diff --git a/app/src/main/java/com/hfut/schedule/logic/enums/BottomBarItems.kt b/app/src/main/java/com/hfut/schedule/logic/enums/BottomBarItems.kt
index b760b14..95b1715 100644
--- a/app/src/main/java/com/hfut/schedule/logic/enums/BottomBarItems.kt
+++ b/app/src/main/java/com/hfut/schedule/logic/enums/BottomBarItems.kt
@@ -1,8 +1,8 @@
package com.hfut.schedule.logic.enums
-enum class BottomBarItems {
- COURSES,
- FOCUS,
- SEARCH,
- SETTINGS
+enum class BottomBarItems(val page : Int) {
+ COURSES(0),
+ FOCUS(1),
+ SEARCH(2),
+ SETTINGS(3)
}
\ No newline at end of file
diff --git a/app/src/main/java/com/hfut/schedule/logic/enums/CardBarItems.kt b/app/src/main/java/com/hfut/schedule/logic/enums/CardBarItems.kt
index 8765bbc..a4853df 100644
--- a/app/src/main/java/com/hfut/schedule/logic/enums/CardBarItems.kt
+++ b/app/src/main/java/com/hfut/schedule/logic/enums/CardBarItems.kt
@@ -1,7 +1,7 @@
package com.hfut.schedule.logic.enums
-enum class CardBarItems {
- BILLS,
- COUNT,
- HOME
+enum class CardBarItems(val page : Int) {
+ BILLS(0),
+ COUNT(1),
+ HOME(2)
}
\ No newline at end of file
diff --git a/app/src/main/java/com/hfut/schedule/logic/enums/FixBarItems.kt b/app/src/main/java/com/hfut/schedule/logic/enums/FixBarItems.kt
index 5f47711..4df30fb 100644
--- a/app/src/main/java/com/hfut/schedule/logic/enums/FixBarItems.kt
+++ b/app/src/main/java/com/hfut/schedule/logic/enums/FixBarItems.kt
@@ -1,5 +1,5 @@
package com.hfut.schedule.logic.enums
-enum class FixBarItems {
- Fix,About
+enum class FixBarItems(val page : Int) {
+ Fix(0),About(1)
}
\ No newline at end of file
diff --git a/app/src/main/java/com/hfut/schedule/logic/enums/GradeBarItems.kt b/app/src/main/java/com/hfut/schedule/logic/enums/GradeBarItems.kt
index 682af99..a10c1b3 100644
--- a/app/src/main/java/com/hfut/schedule/logic/enums/GradeBarItems.kt
+++ b/app/src/main/java/com/hfut/schedule/logic/enums/GradeBarItems.kt
@@ -1,5 +1,5 @@
package com.hfut.schedule.logic.enums
-enum class GradeBarItems {
- GRADE,COUNT
+enum class GradeBarItems(val page : Int) {
+ GRADE(0),COUNT(1)
}
\ No newline at end of file
diff --git a/app/src/main/java/com/hfut/schedule/logic/enums/NewsBarItems.kt b/app/src/main/java/com/hfut/schedule/logic/enums/NewsBarItems.kt
index 553d244..f72a0fe 100644
--- a/app/src/main/java/com/hfut/schedule/logic/enums/NewsBarItems.kt
+++ b/app/src/main/java/com/hfut/schedule/logic/enums/NewsBarItems.kt
@@ -1,5 +1,5 @@
package com.hfut.schedule.logic.enums
-enum class NewsBarItems {
- News,XuanCheng,School
+enum class NewsBarItems(val page : Int) {
+ News(0),XuanCheng(1),School(2)
}
\ No newline at end of file
diff --git a/app/src/main/java/com/hfut/schedule/logic/enums/ShowerBarItems.kt b/app/src/main/java/com/hfut/schedule/logic/enums/ShowerBarItems.kt
index 03ab1e5..35841cc 100644
--- a/app/src/main/java/com/hfut/schedule/logic/enums/ShowerBarItems.kt
+++ b/app/src/main/java/com/hfut/schedule/logic/enums/ShowerBarItems.kt
@@ -1,5 +1,5 @@
package com.hfut.schedule.logic.enums
-enum class ShowerBarItems {
- HOME,BILLS,FUNCTION
+enum class ShowerBarItems(val page : Int) {
+ HOME(0),BILLS(1),FUNCTION(2)
}
\ No newline at end of file
diff --git a/app/src/main/java/com/hfut/schedule/logic/utils/DataStoreManager.kt b/app/src/main/java/com/hfut/schedule/logic/utils/DataStoreManager.kt
index 1ee607e..2b175f3 100644
--- a/app/src/main/java/com/hfut/schedule/logic/utils/DataStoreManager.kt
+++ b/app/src/main/java/com/hfut/schedule/logic/utils/DataStoreManager.kt
@@ -3,25 +3,42 @@ package com.hfut.schedule.logic.utils
import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
+import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.stringSetPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import com.hfut.schedule.App.MyApplication
+import com.hfut.schedule.ui.utils.monet.dataStore
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.map
-class DataStoreManager {
- //构建Preferences DataStore
- private val Context.dataStore: DataStore by
- preferencesDataStore(name = "DataStore")//文件名称
- //创建 DataStore 对象
- val dataStore = MyApplication.context.dataStore
+object DataStoreManager {
+ private val Context.dataStore: DataStore by preferencesDataStore(name = "DataStore")
+ private val dataStore = MyApplication.context.dataStore
- companion object {
- val EXAMPLE_COUNTER = intPreferencesKey("example_counter")
- val EXAMPLE_COUNTER_SET = stringSetPreferencesKey("example_counter_set")
+ private val ANIMATION_TYPE = intPreferencesKey("animation_type")
+
+ suspend fun saveAnimationType(type: Int) {
+ dataStore.edit { preferences ->
+ preferences[ANIMATION_TYPE] = type
+ }
}
+
+ val animationTypeFlow: Flow = dataStore.data
+ .map { preferences ->
+ preferences[ANIMATION_TYPE] ?: 0
+ }
+
+ /* 用法
+ val currentAnimationIndex by DataStoreManager.XXX.collectAsState(initial = 默认值)
+ */
}
+
+
+
//
//fun main() {
// val dataStore = DataStoreManager().dataStore
diff --git a/app/src/main/java/com/hfut/schedule/logic/utils/Starter.kt b/app/src/main/java/com/hfut/schedule/logic/utils/Starter.kt
index fb22c0b..cc6f3d6 100644
--- a/app/src/main/java/com/hfut/schedule/logic/utils/Starter.kt
+++ b/app/src/main/java/com/hfut/schedule/logic/utils/Starter.kt
@@ -91,4 +91,11 @@ object Starter {
MyApplication.context.startActivity(it)
}
+ fun emailMe() {
+ val it = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:zsh0908@outlook.com"))
+ it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ MyApplication.context.startActivity(it)
+ }
+
+
}
diff --git a/app/src/main/java/com/hfut/schedule/logic/utils/getCelebration.kt b/app/src/main/java/com/hfut/schedule/logic/utils/getCelebration.kt
new file mode 100644
index 0000000..6cb5182
--- /dev/null
+++ b/app/src/main/java/com/hfut/schedule/logic/utils/getCelebration.kt
@@ -0,0 +1,16 @@
+package com.hfut.schedule.logic.utils
+
+import com.google.gson.Gson
+import com.hfut.schedule.App.MyApplication
+import com.hfut.schedule.logic.beans.MyAPIResponse
+import com.hfut.schedule.logic.utils.SharePrefs.prefs
+import com.hfut.schedule.viewmodel.NetWorkViewModel
+
+fun getCelebration() : Boolean {
+ val json = prefs.getString("my",MyApplication.NullMy)
+ return try {
+ Gson().fromJson(json,MyAPIResponse::class.java).SettingsInfo.celebration
+ } catch (e: Exception) {
+ false
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/hfut/schedule/ui/activity/card/function/main/home.kt b/app/src/main/java/com/hfut/schedule/ui/activity/card/function/main/home.kt
index 47f114c..cdd0c7c 100644
--- a/app/src/main/java/com/hfut/schedule/ui/activity/card/function/main/home.kt
+++ b/app/src/main/java/com/hfut/schedule/ui/activity/card/function/main/home.kt
@@ -27,7 +27,6 @@ import androidx.compose.material3.CardDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FilledTonalIconButton
import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
import androidx.compose.material3.ListItem
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
@@ -51,7 +50,6 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
-import androidx.compose.ui.window.DialogProperties
import androidx.navigation.NavHostController
import com.hfut.schedule.App.MyApplication
import com.hfut.schedule.R
@@ -74,14 +72,14 @@ import com.hfut.schedule.ui.activity.home.search.functions.electric.EleUI
import com.hfut.schedule.ui.activity.home.search.functions.loginWeb.loginWebUI
import com.hfut.schedule.ui.activity.home.search.functions.shower.ShowerUI
+import com.hfut.schedule.ui.utils.NavigateManager.turnTo
+import com.hfut.schedule.ui.utils.NavigateManager.turnToAndClear
import com.hfut.schedule.ui.utils.style.CardForListColor
-import com.hfut.schedule.ui.utils.components.DividerText
import com.hfut.schedule.ui.utils.components.DividerTextExpandedWith
import com.hfut.schedule.ui.utils.components.MyCard
import com.hfut.schedule.ui.utils.components.MyToast
import com.hfut.schedule.ui.utils.components.WebDialog
import com.hfut.schedule.ui.utils.style.Round
-import com.hfut.schedule.ui.utils.components.WebViewScreen
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@@ -578,13 +576,13 @@ fun HomeScreen(innerPadding : PaddingValues, vm : NetWorkViewModel, navControlle
headlineContent = { Text(text = "账单") },
supportingContent = { Text(text = "按消费先后查看交易记录")},
leadingContent = { Icon(painter = painterResource(id = R.drawable.receipt_long), contentDescription = "") },
- modifier = Modifier.clickable { turnToBottomBar(navController,CardBarItems.BILLS.name) }
+ modifier = Modifier.clickable { turnToAndClear(navController,CardBarItems.BILLS.name) }
)
ListItem(
headlineContent = { Text(text = "统计") },
supportingContent = { Text(text = "按时间段归纳统计消费")},
leadingContent = { Icon(painter = painterResource(id = R.drawable.leaderboard), contentDescription = "") },
- modifier = Modifier.clickable { turnToBottomBar(navController,CardBarItems.COUNT.name) }
+ modifier = Modifier.clickable { turnToAndClear(navController,CardBarItems.COUNT.name) }
)
ListItem(
headlineContent = { Text(text = "充值") },
@@ -652,16 +650,6 @@ fun HomeScreen(innerPadding : PaddingValues, vm : NetWorkViewModel, navControlle
}
}
-fun turnToBottomBar(navController : NavHostController,route : String) {
- navController.navigate(route) {
- popUpTo(navController.graph.startDestinationId) {
- saveState = true
- }
- launchSingleTop = true
- restoreState = true
- }
-}
-
@Composable
fun limitRow(vmUI : UIViewModel) {
val limit by remember { mutableStateOf(vmUI.CardValue.value?.autotrans_limite ?: prefs.getString("card_limit","0")) }
diff --git a/app/src/main/java/com/hfut/schedule/ui/activity/card/main/CardUI.kt b/app/src/main/java/com/hfut/schedule/ui/activity/card/main/CardUI.kt
index 49f37f0..adb7709 100644
--- a/app/src/main/java/com/hfut/schedule/ui/activity/card/main/CardUI.kt
+++ b/app/src/main/java/com/hfut/schedule/ui/activity/card/main/CardUI.kt
@@ -34,6 +34,8 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@@ -58,13 +60,18 @@ import com.hfut.schedule.logic.beans.NavigationBarItemData
import com.hfut.schedule.logic.beans.zjgd.BillResponse
import com.hfut.schedule.logic.beans.zjgd.records
import com.hfut.schedule.logic.utils.AndroidVersion
+import com.hfut.schedule.logic.utils.DataStoreManager
import com.hfut.schedule.logic.utils.SharePrefs
import com.hfut.schedule.logic.utils.SharePrefs.prefs
import com.hfut.schedule.ui.activity.card.function.main.HomeScreen
import com.hfut.schedule.ui.activity.card.bills.main.CardBills
import com.hfut.schedule.ui.activity.card.counts.CardHome
-import com.hfut.schedule.ui.activity.card.function.main.turnToBottomBar
+//import com.hfut.schedule.ui.activity.card.function.main.turnToBottomBar
import com.hfut.schedule.ui.activity.home.focus.funictions.GetZjgdCard
+import com.hfut.schedule.ui.utils.NavigateManager
+import com.hfut.schedule.ui.utils.NavigateManager.currentPage
+import com.hfut.schedule.ui.utils.NavigateManager.turnTo
+import com.hfut.schedule.ui.utils.NavigateManager.turnToAndClear
import com.hfut.schedule.ui.utils.components.CustomTabRow
import com.hfut.schedule.ui.utils.components.MyToast
import com.hfut.schedule.ui.utils.style.bottomBarBlur
@@ -90,7 +97,7 @@ fun CardUI(vm : NetWorkViewModel, vmUI : UIViewModel) {
val navController = rememberNavController()
var page by remember { mutableStateOf(1) }
var loading by remember { mutableStateOf(true) }
- var bottomBarItems by remember { mutableStateOf(CardBarItems.BILLS) }
+ var bottomBarItems by remember { mutableStateOf(CardBarItems.HOME) }
val pagerState = rememberPagerState(pageCount = { 3 })
val titles = listOf("日","月","学期")
@@ -151,6 +158,16 @@ fun CardUI(vm : NetWorkViewModel, vmUI : UIViewModel) {
}
}
+
+
+ val currentAnimationIndex by DataStoreManager.animationTypeFlow.collectAsState(initial = 0)
+// 保存上一页页码 用于决定左右动画
+ if(currentAnimationIndex == 2) {
+ LaunchedEffect(bottomBarItems) {
+ currentPage = bottomBarItems.page
+ }
+ }
+
val context = LocalContext.current
Scaffold(
modifier = Modifier.fillMaxSize(),
@@ -223,7 +240,9 @@ fun CardUI(vm : NetWorkViewModel, vmUI : UIViewModel) {
items[2] -> bottomBarItems = CardBarItems.COUNT
}
// atEnd = !atEnd
- if (!selected) { turnToBottomBar(navController, route) }
+ if (!selected) {
+ turnToAndClear(navController, route)
+ }
},
label = { Text(text = item.label) },
icon = {
@@ -236,16 +255,12 @@ fun CardUI(vm : NetWorkViewModel, vmUI : UIViewModel) {
}
) {innerPadding ->
+ val animation = NavigateManager.getAnimationType(currentAnimationIndex,bottomBarItems.page)
+
NavHost(navController = navController,
startDestination = CardBarItems.HOME.name,
- enterTransition = {
- scaleIn(animationSpec = tween(durationMillis = animation)) +
- expandVertically(expandFrom = Alignment.Top,animationSpec = tween(durationMillis = animation))
- },
- exitTransition = {
- scaleOut(animationSpec = tween(durationMillis = animation)) +
- shrinkVertically(shrinkTowards = Alignment.Top,animationSpec = tween(durationMillis = animation))
- },
+ enterTransition = { animation.enter },
+ exitTransition = { animation.exit },
modifier = Modifier
.haze(
state = hazeState,
diff --git a/app/src/main/java/com/hfut/schedule/ui/activity/fix/about/About.kt b/app/src/main/java/com/hfut/schedule/ui/activity/fix/about/About.kt
index 6edb6c8..67b8882 100644
--- a/app/src/main/java/com/hfut/schedule/ui/activity/fix/about/About.kt
+++ b/app/src/main/java/com/hfut/schedule/ui/activity/fix/about/About.kt
@@ -1,10 +1,9 @@
package com.hfut.schedule.ui.activity.fix.about
-import android.content.Intent
+//import com.hfut.schedule.ui.utils.componentsAbout
+
import android.graphics.Bitmap
import android.graphics.Color
-import android.net.Uri
-import android.widget.Toast
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
@@ -18,11 +17,8 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
-import androidx.compose.material3.Badge
-import androidx.compose.material3.BadgedBox
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.ListItem
@@ -34,7 +30,6 @@ import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@@ -42,7 +37,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.toArgb
-import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
@@ -51,18 +45,16 @@ import com.google.zxing.EncodeHintType
import com.google.zxing.qrcode.QRCodeWriter
import com.hfut.schedule.App.MyApplication
import com.hfut.schedule.R
-import com.hfut.schedule.viewmodel.LoginViewModel
import com.hfut.schedule.logic.utils.APPVersion
import com.hfut.schedule.logic.utils.ClipBoard
import com.hfut.schedule.logic.utils.ShareAPK
import com.hfut.schedule.logic.utils.Starter
import com.hfut.schedule.ui.activity.home.cube.items.main.Screen
import com.hfut.schedule.ui.activity.home.cube.items.subitems.update.VersionInfo
-import com.hfut.schedule.ui.activity.home.cube.items.subitems.update.VersionInfoCard
import com.hfut.schedule.ui.activity.home.cube.items.subitems.update.getUpdates
import com.hfut.schedule.ui.utils.components.MyToast
import com.hfut.schedule.ui.utils.style.Round
-
+import com.hfut.schedule.viewmodel.LoginViewModel
import java.util.Hashtable
@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class)
@@ -124,56 +116,23 @@ fun AboutUI(innerPadding : PaddingValues, vm : LoginViewModel,cubeShow : Boolean
}
}
}
-// val sheetState_github = rememberModalBottomSheetState(skipPartiallyExpanded = true)
-// var showBottomSheet_github by remember { mutableStateOf(false) }
-// if (showBottomSheet_github) {
-// ModalBottomSheet(
-// onDismissRequest = { showBottomSheet_github = false },
-// sheetState = sheetState_github,
-// shape = Round(sheetState_github)
-// ) {
-// Scaffold(
-// modifier = Modifier.fillMaxSize(),
-// topBar = {
-// TopAppBar(
-// colors = TopAppBarDefaults.mediumTopAppBarColors(
-// containerColor = androidx.compose.ui.graphics.Color.Transparent,
-// titleContentColor = MaterialTheme.colorScheme.primary,
-// ),
-// title = { Text("Github") },
-// )
-// },
-// ) { innerPadding ->
-// Column(
-// modifier = Modifier
-// .padding(innerPadding)
-// .verticalScroll(rememberScrollState())
-// .fillMaxSize()
-// ) {
-// val context = LocalContext.current
-// var markdownContent by remember { mutableStateOf("") }
-//
-// val markdownFileName = "README-zh_rCN.md"
-// val inputStream = context.assets.open(markdownFileName)
-// val bufferedReader = BufferedReader(InputStreamReader(inputStream))
-// markdownContent = bufferedReader.use { it.readText() }
-// MarkdownText(
-// markdown = markdownContent,
-// modifier = Modifier.padding(15.dp)
-// )
-// }
-// }
-// }
-// }
- if(!cubeShow) {
- Spacer(modifier = Modifier.height(5.dp))
- VersionInfoCard()
- Spacer(modifier = Modifier.height(18.dp))
+
+ val sheetState_info = rememberModalBottomSheetState(skipPartiallyExpanded = true)
+ var showBottomSheet_info by remember { mutableStateOf(false) }
+ if (showBottomSheet_info) {
+ ModalBottomSheet(
+ onDismissRequest = { showBottomSheet_info = false },
+ sheetState = sheetState_info,
+ shape = Round(sheetState_info)
+ ) {
+ About()
+ }
}
+
ListItem(
headlineContent = { Text(text = "Github开源") },
- supportingContent = { Text(text = "欢迎来参观项目,如您想成为下个版本的构建者,来这里Fork项目并提交你的代码吧")},
+ supportingContent = { Text(text = "如您想成为下个版本的构建者,来这里提交你的代码吧")},
leadingContent = {
Icon(
painterResource(R.drawable.github),
@@ -188,21 +147,6 @@ fun AboutUI(innerPadding : PaddingValues, vm : LoginViewModel,cubeShow : Boolean
// }
}
)
- ListItem(
- headlineContent = { Text(text = "联系开发者") },
- leadingContent = {
- Icon(
- painterResource(R.drawable.mail),
- contentDescription = "Localized description",
- )
- },
- modifier = Modifier.clickable{
- val it = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:zsh0908@outlook.com"))
- it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- MyApplication.context.startActivity(it)
- }
- )
-
ListItem(
headlineContent = { Text(text = "推广本应用") },
@@ -231,23 +175,6 @@ fun AboutUI(innerPadding : PaddingValues, vm : LoginViewModel,cubeShow : Boolean
var showBadge by remember { mutableStateOf(false) }
if (version.version != APPVersion.getVersionName()) showBadge = true
- ListItem(
- headlineContent = { Text(text = "获取更新") },
- supportingContent = { Text(text = if(version.version == APPVersion.getVersionName()) "当前为最新版本 ${APPVersion.getVersionName()}" else "当前版本 ${APPVersion.getVersionName()}\n最新版本 ${version.version}") },
- leadingContent = {
- BadgedBox(badge = {
- if(showBadge)
- Badge(modifier = Modifier.size(7.dp)) }) {
- Icon(painterResource(R.drawable.arrow_upward), contentDescription = "Localized description",)
- }
- },
- modifier = Modifier.clickable{
- if (version.version != APPVersion.getVersionName())
- Starter.startWebUrl(MyApplication.UpdateURL + "releases/download/Android/${version.version}.apk")
- else Toast.makeText(MyApplication.context,"与云端版本一致", Toast.LENGTH_SHORT).show()
- }
- )
-
ListItem(
headlineContent = { Text(text = "本版本新特性") },
supportingContent = { Text(text = "查看此版本的更新内容")},
@@ -256,14 +183,10 @@ fun AboutUI(innerPadding : PaddingValues, vm : LoginViewModel,cubeShow : Boolean
)
ListItem(
- headlineContent = { Text(text = "版本日志") },
- supportingContent = { Text("查看历代版本的更新内容") },
- leadingContent = {
- Icon(painterResource(R.drawable.crossword), contentDescription = "Localized description",)
- },
- modifier = Modifier.clickable{
- Starter.startWebUrl("https://github.com/Chiu-xaH/HFUT-Schedule/blob/main/UPDATE.md")
- }
+ headlineContent = { Text(text = "关于本应用") },
+ supportingContent = { Text(text = "开源 构建 开发者")},
+ modifier = Modifier.clickable { showBottomSheet_info = true },
+ leadingContent = { Icon(painter = painterResource(id = R.drawable.info), contentDescription = "")}
)
diff --git a/app/src/main/java/com/hfut/schedule/ui/activity/fix/about/AboutDeveloper.kt b/app/src/main/java/com/hfut/schedule/ui/activity/fix/about/AboutDeveloper.kt
new file mode 100644
index 0000000..9745898
--- /dev/null
+++ b/app/src/main/java/com/hfut/schedule/ui/activity/fix/about/AboutDeveloper.kt
@@ -0,0 +1,182 @@
+package com.hfut.schedule.ui.activity.fix.about
+
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material3.Button
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.FilledTonalButton
+import androidx.compose.material3.FilledTonalIconButton
+import androidx.compose.material3.Icon
+import androidx.compose.material3.LargeTopAppBar
+import androidx.compose.material3.ListItem
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.material3.TopAppBarDefaults
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.hfut.schedule.R
+import com.hfut.schedule.logic.utils.Starter
+import com.hfut.schedule.ui.utils.components.DividerTextExpandedWith
+import com.hfut.schedule.ui.utils.components.ScrollText
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+@Preview
+fun About() {
+ data class Build(
+ val languages : List,
+ val build : List,
+ val ui : String,
+ val jetpack : String
+ )
+ val openSourceProjects = listOf(
+ "Okhttp" to "网络请求",
+ "Retrofit" to "网络请求",
+ "Gson" to "JSON解析",
+ "Jsoup" to "XML/HTML解析",
+ "Zxing" to "二维码",
+ "Haze" to "实时模糊(SDK>=33)",
+ "Accompanist" to "用做实现透明状态栏",
+ "Monet" to "莫奈取色(供SDK<32不支持MY取色平替)",
+ "Dagger" to "Hilt注入,辅助莫奈取色功能",
+ "Glide" to "网络图片",
+ "EdDSA Java" to "加密(供和风天气API使用)",
+ "Konfetti" to "礼花动画",
+ )
+ val dependencies = Build(
+ jetpack = "Jetpack Compose",
+ ui = "Material Design 3 (Material You)",
+ languages = listOf("Kotlin","Java"),
+ build = listOf( "Gradle 8.3 With Groovy","OpenJDK 17"),
+ )
+// var showBottomSheet by remember { mutableStateOf(false) }
+// UseAgreement(showBottomSheet, showBottomSheetChange = { showBottomSheet = false })
+
+ androidx.compose.material3.Scaffold(
+ topBar = {
+ LargeTopAppBar(
+ colors = TopAppBarDefaults.mediumTopAppBarColors(
+ containerColor = Color.Transparent,
+ titleContentColor = MaterialTheme.colorScheme.primary,
+ ),
+ title = {
+ Box(modifier = Modifier.fillMaxWidth()) {
+ Text(
+ text = "关于",
+ modifier = Modifier.fillMaxWidth(),
+ textAlign = TextAlign.Center,
+ //style = MaterialTheme.typography.titleLarge
+ )
+ }
+ },
+ navigationIcon = {
+ Column(modifier = Modifier
+ .padding(horizontal = 23.dp)) {
+ Spacer(modifier = Modifier.height(20.dp))
+ Text(
+ text = "聚在工大",
+ fontSize = 38.sp,
+ color = MaterialTheme.colorScheme.secondaryContainer
+ )
+ }
+ },
+ )
+ },
+ bottomBar = {
+ Row(modifier = Modifier.padding(15.dp),horizontalArrangement = Arrangement.Center) {
+ Button(
+ onClick = { Starter.startWebUrl("https://github.com/Chiu-xaH/HFUT-Schedule") },
+ modifier = Modifier
+ .fillMaxWidth()
+ .weight(.5f)
+ ) {
+ Text("给颗⭐")
+ }
+
+ Spacer(modifier = Modifier.width(15.dp))
+ FilledTonalButton(
+ onClick = { Starter.startWebUrl("https://github.com/Chiu-xaH") },
+ modifier = Modifier
+ .fillMaxWidth()
+ .weight(.5f)
+ ) {
+ Text("我的Github")
+ }
+ }
+ },
+ ) { innerPadding ->
+ Column(modifier = Modifier.padding(innerPadding).verticalScroll(rememberScrollState())) {
+ DividerTextExpandedWith("开发者") {
+ ListItem(
+ modifier = Modifier.clickable {
+ Starter.startWebUrl("https://github.com/Chiu-xaH")
+ },
+ headlineContent = { ScrollText("Chiu-xaH") },
+ leadingContent = { Icon(painterResource(R.drawable.github), null) },
+ supportingContent = {
+ Text("一名热爱安卓的开发者,宣城校区23级计算机科学与技术专业(转)本科生")
+ },
+ trailingContent = {
+ FilledTonalIconButton(
+ onClick = {
+ Starter.emailMe()
+ }
+ ) {
+ Icon(painterResource(R.drawable.mail),null)
+ }
+ }
+ )
+
+ }
+
+ DividerTextExpandedWith("构建") {
+ val lans = dependencies.languages
+ for(index in lans.indices) {
+ ListItem(
+ headlineContent = { Text(lans[index]) },
+ overlineContent = { Text("主体语言") }
+ )
+ }
+ ListItem(
+ headlineContent = { Text(dependencies.ui) },
+ overlineContent = { Text("UI设计") }
+ )
+ ListItem(
+ headlineContent = { Text(dependencies.jetpack) },
+ )
+ val builds = dependencies.build
+ for(index in builds.indices) {
+ ListItem(
+ headlineContent = { Text(builds[index]) },
+ overlineContent = { Text("构建 打包") }
+ )
+ }
+ }
+
+ DividerTextExpandedWith("开源") {
+ for(index in openSourceProjects.indices) {
+ ListItem(
+ headlineContent = { Text(openSourceProjects[index].first) },
+ supportingContent = { Text(openSourceProjects[index].second) }
+ )
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/hfut/schedule/ui/activity/fix/fix/FixUI.kt b/app/src/main/java/com/hfut/schedule/ui/activity/fix/fix/FixUI.kt
index 06d1da9..1d2e572 100644
--- a/app/src/main/java/com/hfut/schedule/ui/activity/fix/fix/FixUI.kt
+++ b/app/src/main/java/com/hfut/schedule/ui/activity/fix/fix/FixUI.kt
@@ -53,6 +53,7 @@ import com.hfut.schedule.logic.utils.CrashHandler
import com.hfut.schedule.logic.utils.SharePrefs
import com.hfut.schedule.logic.utils.SharePrefs.prefs
import com.hfut.schedule.logic.utils.Starter
+import com.hfut.schedule.logic.utils.Starter.emailMe
import com.hfut.schedule.ui.activity.home.cube.items.main.Clear
import com.hfut.schedule.ui.activity.home.cube.items.main.apiCheck
import com.hfut.schedule.ui.activity.home.focus.funictions.getTimeStamp
@@ -429,7 +430,7 @@ fun feedBackUI(vm : NetWorkViewModel) {
ListItem(
headlineContent = { Text(text = "或者通过电子邮件联系") },
leadingContent = { Icon(painter = painterResource(id = R.drawable.mail), contentDescription ="" )},
- modifier = Modifier.clickable { sendToMe() }
+ modifier = Modifier.clickable { emailMe() }
)
}
MyCard {
diff --git a/app/src/main/java/com/hfut/schedule/ui/activity/fix/main/Fix.kt b/app/src/main/java/com/hfut/schedule/ui/activity/fix/main/Fix.kt
index 1ea5544..05e08b0 100644
--- a/app/src/main/java/com/hfut/schedule/ui/activity/fix/main/Fix.kt
+++ b/app/src/main/java/com/hfut/schedule/ui/activity/fix/main/Fix.kt
@@ -30,6 +30,8 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@@ -51,10 +53,14 @@ import com.hfut.schedule.viewmodel.LoginViewModel
import com.hfut.schedule.logic.enums.FixBarItems
import com.hfut.schedule.logic.beans.NavigationBarItemData
import com.hfut.schedule.logic.utils.AndroidVersion
+import com.hfut.schedule.logic.utils.DataStoreManager
import com.hfut.schedule.logic.utils.SharePrefs
import com.hfut.schedule.logic.utils.SharePrefs.prefs
import com.hfut.schedule.ui.activity.fix.about.AboutUI
import com.hfut.schedule.ui.activity.fix.fix.FixUI
+import com.hfut.schedule.ui.utils.NavigateManager
+import com.hfut.schedule.ui.utils.NavigateManager.currentPage
+import com.hfut.schedule.ui.utils.NavigateManager.turnToAndClear
import com.hfut.schedule.ui.utils.style.bottomBarBlur
import com.hfut.schedule.ui.utils.style.topBarBlur
import dev.chrisbanes.haze.HazeState
@@ -69,6 +75,16 @@ fun Fix(vm : LoginViewModel,vm2 : NetWorkViewModel) {
var animation by remember { mutableStateOf(prefs.getInt("ANIMATION", MyApplication.Animation)) }
val hazeState = remember { HazeState() }
val navController = rememberNavController()
+ val currentAnimationIndex by DataStoreManager.animationTypeFlow.collectAsState(initial = 0)
+ var targetPage by remember { mutableStateOf(FixBarItems.Fix) }
+ // 保存上一页页码 用于决定左右动画
+ if(currentAnimationIndex == 2) {
+ LaunchedEffect(targetPage) {
+ currentPage = targetPage.page
+ }
+ }
+
+
val context = LocalContext.current
Scaffold(
modifier = Modifier.fillMaxSize(),
@@ -125,15 +141,16 @@ fun Fix(vm : LoginViewModel,vm2 : NetWorkViewModel) {
modifier = Modifier.scale(scale.value),
interactionSource = interactionSource,
onClick = {
- if (!selected) {
- navController.navigate(route) {
- popUpTo(navController.graph.startDestinationId) {
- saveState = true
- }
- launchSingleTop = true
- restoreState = true
+ if(currentAnimationIndex == 2) {
+ when(item){
+ items[0] -> targetPage = FixBarItems.Fix
+ items[0] -> targetPage = FixBarItems.About
}
}
+
+ if (!selected) {
+ turnToAndClear(navController,route)
+ }
},
label = { Text(text = item.label) },
icon = {
@@ -146,16 +163,12 @@ fun Fix(vm : LoginViewModel,vm2 : NetWorkViewModel) {
}
) {innerPadding ->
+ val animation = NavigateManager.getAnimationType(currentAnimationIndex,targetPage.page)
+
NavHost(navController = navController,
startDestination = FixBarItems.Fix.name,
- enterTransition = {
- scaleIn(animationSpec = tween(durationMillis = animation)) +
- expandVertically(expandFrom = Alignment.Top,animationSpec = tween(durationMillis = animation))
- },
- exitTransition = {
- scaleOut(animationSpec = tween(durationMillis = animation)) +
- shrinkVertically(shrinkTowards = Alignment.Top,animationSpec = tween(durationMillis = animation))
- },
+ enterTransition = { animation.enter },
+ exitTransition = { animation.exit },
modifier = Modifier
.haze(
state = hazeState,
diff --git a/app/src/main/java/com/hfut/schedule/ui/activity/grade/main/GradeUI.kt b/app/src/main/java/com/hfut/schedule/ui/activity/grade/main/GradeUI.kt
index 198acc7..b399b02 100644
--- a/app/src/main/java/com/hfut/schedule/ui/activity/grade/main/GradeUI.kt
+++ b/app/src/main/java/com/hfut/schedule/ui/activity/grade/main/GradeUI.kt
@@ -35,6 +35,8 @@ import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
@@ -55,12 +57,17 @@ import androidx.navigation.compose.rememberNavController
import com.hfut.schedule.App.MyApplication
import com.hfut.schedule.R
import com.hfut.schedule.logic.beans.NavigationBarItemData
+import com.hfut.schedule.logic.enums.FixBarItems
import com.hfut.schedule.logic.enums.GradeBarItems
import com.hfut.schedule.logic.utils.AndroidVersion
+import com.hfut.schedule.logic.utils.DataStoreManager
import com.hfut.schedule.logic.utils.SharePrefs.prefs
import com.hfut.schedule.ui.activity.grade.analysis.GradeCountUI
import com.hfut.schedule.ui.activity.grade.grade.community.GradeItemUI
import com.hfut.schedule.ui.activity.grade.grade.jxglstu.GradeItemUIJXGLSTU
+import com.hfut.schedule.ui.utils.NavigateManager
+import com.hfut.schedule.ui.utils.NavigateManager.currentPage
+import com.hfut.schedule.ui.utils.NavigateManager.turnToAndClear
import com.hfut.schedule.ui.utils.components.MyCard
import com.hfut.schedule.ui.utils.style.Round
import com.hfut.schedule.ui.utils.style.bottomBarBlur
@@ -86,6 +93,16 @@ fun GradeUI(ifSaved : Boolean,vm : NetWorkViewModel) {
var showBottomSheet by remember { mutableStateOf(false) }
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
+ val currentAnimationIndex by DataStoreManager.animationTypeFlow.collectAsState(initial = 0)
+ var targetPage by remember { mutableStateOf(GradeBarItems.GRADE) }
+ // 保存上一页页码 用于决定左右动画
+ if(currentAnimationIndex == 2) {
+ LaunchedEffect(targetPage) {
+ currentPage = targetPage.page
+ }
+ }
+
+
if (showBottomSheet) {
ModalBottomSheet(
onDismissRequest = { showBottomSheet= false },
@@ -180,15 +197,16 @@ fun GradeUI(ifSaved : Boolean,vm : NetWorkViewModel) {
modifier = Modifier.scale(scale.value),
interactionSource = interactionSource,
onClick = {
- if (!selected) {
- navController.navigate(route) {
- popUpTo(navController.graph.startDestinationId) {
- saveState = true
- }
- launchSingleTop = true
- restoreState = true
+ if(currentAnimationIndex == 2) {
+ when(item) {
+ items[0] -> targetPage = GradeBarItems.GRADE
+ items[1] -> targetPage = GradeBarItems.COUNT
}
}
+
+ if (!selected) {
+ turnToAndClear(navController,route)
+ }
},
label = { Text(text = item.label) },
icon = {
@@ -201,16 +219,12 @@ fun GradeUI(ifSaved : Boolean,vm : NetWorkViewModel) {
}
) { innerPadding ->
- NavHost(navController = navController,
+ val animation = NavigateManager.getAnimationType(currentAnimationIndex,targetPage.page)
+
+ NavHost(navController = navController,
startDestination = GradeBarItems.GRADE.name,
- enterTransition = {
- scaleIn(animationSpec = tween(durationMillis = animation)) +
- expandVertically(expandFrom = Alignment.Top,animationSpec = tween(durationMillis = animation))
- },
- exitTransition = {
- scaleOut(animationSpec = tween(durationMillis = animation)) +
- shrinkVertically(shrinkTowards = Alignment.Top,animationSpec = tween(durationMillis = animation))
- },
+ enterTransition = { animation.enter },
+ exitTransition = { animation.exit },
modifier = Modifier.haze(state = hazeState)
) {
composable(GradeBarItems.GRADE.name) {
diff --git a/app/src/main/java/com/hfut/schedule/ui/activity/home/calendar/communtiy/SavedCourseUISwap.kt b/app/src/main/java/com/hfut/schedule/ui/activity/home/calendar/communtiy/SavedCourseUISwap.kt
index d781f87..b14f2a3 100644
--- a/app/src/main/java/com/hfut/schedule/ui/activity/home/calendar/communtiy/SavedCourseUISwap.kt
+++ b/app/src/main/java/com/hfut/schedule/ui/activity/home/calendar/communtiy/SavedCourseUISwap.kt
@@ -841,20 +841,14 @@ fun ScheduleTopDate(showAll: Boolean,today : LocalDate,blur : Boolean) {
LazyVerticalGrid(columns = GridCells.Fixed(if(showAll)7 else 5),modifier = Modifier.padding(horizontal = 10.dp)){
items(if(showAll)7 else 5) { item ->
val date = mondayOfCurrentWeek.plusDays(item.toLong()).toString() //YYYY-MM-DD 与考试对比
+ val isToday = date == DateTimeManager.Date_yyyy_MM_dd
if (Benweeks > 0)
Text(
text = date.substringAfter("-"),
textAlign = TextAlign.Center,
fontSize = if(showAll)12.sp else 14.sp,
- color = if(date == DateTimeManager.Date_yyyy_MM_dd) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.primary,
-// style = if(date == DateTimeManager.Date_yyyy_MM_dd) {
-// TextStyle(shadow = Shadow(
-// color = Color.Gray,
-// offset = Offset(2.0f,2.0f),
-// blurRadius = 7.0f
-// ))
-// } else TextStyle(),
- fontWeight = if(date == DateTimeManager.Date_yyyy_MM_dd) FontWeight.Bold else FontWeight.Normal
+ color = if(isToday) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.primary,
+ fontWeight = if(isToday) FontWeight.Bold else FontWeight.Normal
)
else Text(
text = "未开学",
diff --git a/app/src/main/java/com/hfut/schedule/ui/activity/home/cube/items/NavUIs/UIScreen.kt b/app/src/main/java/com/hfut/schedule/ui/activity/home/cube/items/NavUIs/UIScreen.kt
index dad5da8..a4889e9 100644
--- a/app/src/main/java/com/hfut/schedule/ui/activity/home/cube/items/NavUIs/UIScreen.kt
+++ b/app/src/main/java/com/hfut/schedule/ui/activity/home/cube/items/NavUIs/UIScreen.kt
@@ -11,34 +11,25 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Icon
import androidx.compose.material3.ListItem
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Slider
-import androidx.compose.material3.SliderDefaults
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
-import com.hfut.schedule.App.MyApplication
import com.hfut.schedule.R
import com.hfut.schedule.logic.utils.AndroidVersion.canBlur
-import com.hfut.schedule.logic.utils.SharePrefs
-import com.hfut.schedule.logic.utils.SharePrefs.prefs
import com.hfut.schedule.logic.utils.SharePrefs.saveBoolean
+import com.hfut.schedule.ui.activity.home.cube.items.subitems.AnimationSetting
import com.hfut.schedule.ui.activity.home.cube.items.subitems.monet.MonetColorItem
import com.hfut.schedule.ui.utils.BlurManager
-import com.hfut.schedule.ui.utils.components.DividerText
import com.hfut.schedule.ui.utils.components.DividerTextExpandedWith
-import com.hfut.schedule.ui.utils.components.MyToast
-import java.math.BigDecimal
-import java.math.RoundingMode
@Composable
fun UIScreen(navController: NavController, innerPaddings : PaddingValues,
@@ -59,10 +50,6 @@ fun UIScreen(navController: NavController, innerPaddings : PaddingValues,
saveBoolean("SWITCHBLUR",true,blur)
- var sliderPosition by remember { mutableFloatStateOf((prefs.getInt("ANIMATION", MyApplication.Animation)).toFloat()) }
- val bd = BigDecimal(sliderPosition.toString())
- val str = bd.setScale(0, RoundingMode.HALF_UP).toString()
- SharePrefs.saveInt("ANIMATION",sliderPosition.toInt())
ListItem(
headlineContent = { Text(text = "底栏标签") },
@@ -104,45 +91,16 @@ fun UIScreen(navController: NavController, innerPaddings : PaddingValues,
BlurManager.setValue(animationBlur)
}
)
+ val cor = rememberCoroutineScope()
ListItem(
- headlineContent = { Text(text = "全局动画速度") },
+ headlineContent = { Text(text = "底栏转场动画") },
supportingContent = {
- Column {
- Text(text = "时长 $str ms 重启后生效")
- Slider(
- value = sliderPosition,
- onValueChange = {
- sliderPosition = it
- SharePrefs.saveInt("ANIMATION",sliderPosition.toInt())
- },
- colors = SliderDefaults.colors(
- thumbColor = MaterialTheme.colorScheme.secondary,
- activeTrackColor = MaterialTheme.colorScheme.secondary,
- inactiveTrackColor = MaterialTheme.colorScheme.secondaryContainer,
- ),
- steps = 19,
- valueRange = 0f..1000f
- )
- }
- },
- leadingContent = { Icon(painterResource(R.drawable.schedule), contentDescription = "Localized description",) },
- trailingContent = { },
- )
-
- ListItem(
- headlineContent = { Text(text = "界面转场动画") },
- supportingContent = {
- Text("自定义同级页面之间进行转场的动画")
+ Text("自定义底栏切换页面进行转场的动画")
},
leadingContent = { Icon(painterResource(R.drawable.animation), contentDescription = "Localized description",) },
-// trailingContent = { },
- modifier = Modifier.clickable {
- MyToast("正在开发")
-// animationBlur = !animationBlur
-// BlurManager.setValue(animationBlur)
- }
)
+ AnimationSetting()
}
DividerTextExpandedWith("主题色") {
diff --git a/app/src/main/java/com/hfut/schedule/ui/activity/home/cube/items/subitems/AnimationSetting.kt b/app/src/main/java/com/hfut/schedule/ui/activity/home/cube/items/subitems/AnimationSetting.kt
new file mode 100644
index 0000000..5649d5f
--- /dev/null
+++ b/app/src/main/java/com/hfut/schedule/ui/activity/home/cube/items/subitems/AnimationSetting.kt
@@ -0,0 +1,131 @@
+package com.hfut.schedule.ui.activity.home.cube.items.subitems
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.lazy.LazyRow
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.CardDefaults
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.OutlinedCard
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import com.hfut.schedule.logic.utils.DataStoreManager
+import com.hfut.schedule.ui.utils.NavigateManager
+import com.hfut.schedule.ui.utils.NavigateManager.ANIMATION_SPEED
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+
+// DataStore 用法
+@Composable
+@Preview
+fun AnimationSetting() {
+ val lists = listOf(
+ NavigateManager.upDownAnimation,
+ NavigateManager.centerAnimation,
+ NavigateManager.getLeftRightAnimation(0),
+ NavigateManager.fadeAnimation,
+ NavigateManager.nullAnimation
+ )
+ val currentAnimationIndex by DataStoreManager.animationTypeFlow.collectAsState(initial = 0)
+
+ LazyRow() {
+ item { Spacer(Modifier.width(10.dp)) }
+ items(lists.size) { index ->
+ Spacer(Modifier.width(5.dp))
+ AnimationCard(lists[index],currentAnimationIndex,index)
+ }
+ item {
+ Spacer(Modifier.width(15.dp))
+ }
+ }
+}
+
+@Composable
+fun AnimationCard(animation : NavigateManager. TransferAnimation, currentAnimationIndex : Int, index : Int) {
+ val isSelected = currentAnimationIndex == index
+
+ val cor = rememberCoroutineScope()
+ Column(verticalArrangement = Arrangement.Center,
+ horizontalAlignment = Alignment.CenterHorizontally) {
+ OutlinedCard (
+ modifier = Modifier
+ .width(100.dp)
+ .height(180.dp)
+ .clickable {
+ // 点击选择应用动画 标记selected=true selected只能存在一个true
+ cor.launch { DataStoreManager.saveAnimationType(index) }
+ },
+ border = CardDefaults.outlinedCardBorder(enabled = isSelected),
+ shape = RoundedCornerShape(16.dp),
+ ) {
+ Box (
+ modifier = Modifier.fillMaxSize().padding(5.dp),
+ ) {
+ var visible by remember { mutableStateOf(true) }
+ LaunchedEffect(Unit) {
+ while (true) {
+ visible = !visible
+ delay((ANIMATION_SPEED * 2).toLong()) // 延迟时间可以根据需要调整
+ }
+ }
+
+ androidx.compose.animation.AnimatedVisibility(
+ visible = visible,
+ enter = animation.enter,
+ exit = animation.exit,
+ modifier = Modifier.align(Alignment.Center)
+ ) {
+ Box(
+ modifier = Modifier
+ .fillMaxSize()
+ .background(MaterialTheme.colorScheme.primaryContainer, shape = RoundedCornerShape(14.dp))
+ ) {
+ Text("2", modifier = Modifier.align(Alignment.Center))
+ }
+ }
+ androidx.compose.animation.AnimatedVisibility(
+ visible = !visible,
+ enter = animation.enter,
+ exit = animation.exit,
+ modifier = Modifier.align(Alignment.Center)
+ ) {
+ Box(
+ modifier = Modifier
+ .fillMaxSize()
+ .background(MaterialTheme.colorScheme.primaryContainer.copy(.5f), shape = RoundedCornerShape(14.dp))
+ ) {
+ Text("1", modifier = Modifier.align(Alignment.Center))
+ }
+ }
+ }
+ }
+ Spacer(Modifier.height(2.dp))
+ Text(text = animation.remark, style = MaterialTheme.typography.titleSmall,
+ color = if(isSelected) MaterialTheme.colorScheme.onPrimaryContainer else Color.Gray,
+ fontWeight = if(isSelected) FontWeight.Bold else FontWeight.Normal
+ )
+ }
+
+}
diff --git a/app/src/main/java/com/hfut/schedule/ui/activity/home/cube/items/subitems/Test.kt b/app/src/main/java/com/hfut/schedule/ui/activity/home/cube/items/subitems/Test.kt
index 2a5b716..fc14237 100644
--- a/app/src/main/java/com/hfut/schedule/ui/activity/home/cube/items/subitems/Test.kt
+++ b/app/src/main/java/com/hfut/schedule/ui/activity/home/cube/items/subitems/Test.kt
@@ -89,9 +89,16 @@ import com.hfut.schedule.ui.utils.style.CardForListColor
import com.hfut.schedule.ui.utils.style.RowHorizal
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
+import nl.dionsegijn.konfetti.compose.KonfettiView
+import nl.dionsegijn.konfetti.core.Party
+import nl.dionsegijn.konfetti.core.Position
+import nl.dionsegijn.konfetti.core.emitter.Emitter
+import nl.dionsegijn.konfetti.core.models.Shape
+import nl.dionsegijn.konfetti.core.models.Size
+import java.util.concurrent.TimeUnit
import kotlin.math.roundToInt
-@OptIn(ExperimentalMaterial3Api::class, ExperimentalSharedTransitionApi::class)
+@OptIn(ExperimentalSharedTransitionApi::class)
@Composable
fun TEST(innerPaddings : PaddingValues) {
// Column (modifier = Modifier.padding(innerPaddings)){
@@ -224,44 +231,85 @@ fun TEST(innerPaddings : PaddingValues) {
//
// // Gesture()
// }
- val listSnacks = listOf(
- Snack("桌面","des",R.drawable.home),
- Snack("搜索","des",R.drawable.search),
- Snack("动画","des",R.drawable.animation),
- Snack("堆栈","des",R.drawable.stacks)
+
+
+ val party = Party(
+ emitter = Emitter(duration = 5, TimeUnit.SECONDS).perSecond(30)
)
- SharedTransitionLayout {
- val navController = rememberNavController()
- NavHost(
- navController = navController,
- startDestination = "home"
- ) {
- composable("home") {
- HomeScreen(
- navController,
- this@SharedTransitionLayout,
- this@composable,
- listSnacks,
- innerPaddings
- )
- }
- composable(
- "details/{item}",
- arguments = listOf(navArgument("item") { type = NavType.IntType })
- ) { backStackEntry ->
- val id = backStackEntry.arguments?.getInt("item")
- val snack = listSnacks[id!!]
- DetailsScreen(
- navController,
- id,
- snack,
- this@SharedTransitionLayout,
- this@composable
- )
+ Box() {
+ KonfettiView(
+ modifier = Modifier.fillMaxSize(),
+ parties = listOf(party),
+ )
+ val listSnacks = listOf(
+ Snack("桌面","des",R.drawable.home),
+ Snack("搜索","des",R.drawable.search),
+ Snack("动画","des",R.drawable.animation),
+ Snack("堆栈","des",R.drawable.stacks)
+ )
+
+ SharedTransitionLayout {
+ val navController = rememberNavController()
+ NavHost(
+ navController = navController,
+ startDestination = "home"
+ ) {
+ composable("home") {
+ HomeScreen(
+ navController,
+ this@SharedTransitionLayout,
+ this@composable,
+ listSnacks,
+ innerPaddings
+ )
+ }
+ composable(
+ "details/{item}",
+ arguments = listOf(navArgument("item") { type = NavType.IntType })
+ ) { backStackEntry ->
+ val id = backStackEntry.arguments?.getInt("item")
+ val snack = listSnacks[id!!]
+ DetailsScreen(
+ navController,
+ id,
+ snack,
+ this@SharedTransitionLayout,
+ this@composable
+ )
+ }
}
}
}
+
+}
+
+@Composable
+@Preview
+fun t() {
+ val partyTopStart = Party(
+ emitter = Emitter(duration = 1, TimeUnit.SECONDS).perSecond(30),
+ position = Position.Relative(0.0,0.0)
+ )
+ val partyTopEnd = Party(
+ emitter = Emitter(duration = 1, TimeUnit.SECONDS).perSecond(30),
+ position = Position.Relative(1.0,0.0)
+ )
+ val partyBottomStart = Party(
+ emitter = Emitter(duration = 1, TimeUnit.SECONDS).perSecond(30),
+ position = Position.Relative(0.0,1.0)
+ )
+ val partyBottomEnd = Party(
+ emitter = Emitter(duration = 1, TimeUnit.SECONDS).perSecond(30),
+ position = Position.Relative(1.0,1.0)
+ )
+
+ Box(modifier = Modifier.fillMaxSize()) {
+ KonfettiView(
+ modifier = Modifier.fillMaxSize(),
+ parties = listOf(partyTopStart,partyTopEnd,partyBottomStart,partyBottomEnd),
+ )
+ }
}
@OptIn(ExperimentalAnimationGraphicsApi::class)
diff --git a/app/src/main/java/com/hfut/schedule/ui/activity/home/cube/items/subitems/update/UpdateItem.kt b/app/src/main/java/com/hfut/schedule/ui/activity/home/cube/items/subitems/update/UpdateItem.kt
index 4dea33a..5f7114f 100644
--- a/app/src/main/java/com/hfut/schedule/ui/activity/home/cube/items/subitems/update/UpdateItem.kt
+++ b/app/src/main/java/com/hfut/schedule/ui/activity/home/cube/items/subitems/update/UpdateItem.kt
@@ -31,15 +31,15 @@ import com.hfut.schedule.ui.utils.style.CardForListColor
@SuppressLint("SuspiciousIndentation")
@Composable
fun VersionInfoCard() {
- if(APPVersion.getVersionName().contains("Preview")) {
- Card(
- elevation = CardDefaults.cardElevation(defaultElevation = 15.dp),
- modifier = Modifier
- .fillMaxWidth()
- .padding(horizontal = 15.dp, vertical = 5.dp),
- shape = MaterialTheme.shapes.medium,
- ) { ListItem(headlineContent = { Text(text = APPVersion.getVersionName(), fontSize = 28.sp) }) }
- } else
+// if(APPVersion.getVersionName().contains("Preview")) {
+// Card(
+// elevation = CardDefaults.cardElevation(defaultElevation = 15.dp),
+// modifier = Modifier
+// .fillMaxWidth()
+// .padding(horizontal = 15.dp, vertical = 5.dp),
+// shape = MaterialTheme.shapes.medium,
+// ) { ListItem(headlineContent = { Text(text = APPVersion.getVersionName(), fontSize = 28.sp) }) }
+// } else
Card(
elevation = CardDefaults.cardElevation(defaultElevation = 15.dp),
modifier = Modifier
@@ -48,22 +48,22 @@ fun VersionInfoCard() {
shape = MaterialTheme.shapes.medium,
colors = CardForListColor()
) {
- ListItem(headlineContent = { Text(text = "聚在工大 " + APPVersion.getVersionName(), fontSize = 28.sp) })
+ ListItem(headlineContent = { Text(text = "版本 " + APPVersion.getVersionName(), fontSize = 28.sp) })
Row {
ListItem(
- overlineContent = { Text(text = "2025-01-27") },
- leadingContent = { Icon(painter = painterResource(id = R.drawable.sdk), contentDescription = "") },
- headlineContent = { ScrollText(text = "第${APPVersion.getVersionCode()}次更新") },
- modifier = Modifier.weight(.5f)
- )
- ListItem(
- headlineContent = { Text(text = "Chiu-xaH\ntinyvan") },
- overlineContent = { Text(text = "构建") },
- leadingContent = { Icon(painter = painterResource(id = R.drawable.support), contentDescription = "") },
- modifier = Modifier.weight(.5f).clickable {
- MyToast("想成为下个版本的构建者吗?跟随 设置-维护关于-开源主页")
- }
+ overlineContent = { Text(text = "2025-01-30") },
+ leadingContent = { Icon(painter = painterResource(id = R.drawable.code), contentDescription = "") },
+ headlineContent = { Text(text = "版本号 ${APPVersion.getVersionCode()}") },
+// modifier = Modifier.weight(.5f)
)
+// ListItem(
+// headlineContent = { Text(text = "Chiu-xaH") },
+// overlineContent = { Text(text = "构建") },
+// leadingContent = { Icon(painter = painterResource(id = R.drawable.support), contentDescription = "") },
+// modifier = Modifier.weight(.5f).clickable {
+// MyToast("想成为下个版本的构建者吗?跟随 设置-维护关于-开源主页")
+// }
+// )
}
}
}
@@ -75,9 +75,11 @@ fun VersionInfo() {
Spacer(Modifier.height(3.dp))
VersionInfoCard()
DividerTextExpandedWith(text = "新特性") {
- UpdateItems("新增 邮箱","可在此处查看自己的学生邮箱,用于接收高校优惠的验证码", UpdateType.ADD)
- UpdateItems("修复 校园网在合肥校区的某些Bug", null, UpdateType.FIX)
- UpdateItems("优化 部分界面的显示", null, UpdateType.OPTIMIZE)
+ UpdateItems("新增 节日开屏礼花", null, UpdateType.ADD)
+ UpdateItems("新增 用户协议", null, UpdateType.ADD)
+ UpdateItems("新增 底栏转场动画", "位于选项-界面显示,有5种动画自定义", UpdateType.ADD)
+ UpdateItems("重构 关于", "删减冗余的选项;新增 关于本应用,位于 选项-维护关于", UpdateType.RENEW)
+ UpdateItems("移除 转场动画时长自定义", "强制所有动画为默认值400ms", UpdateType.DEGREE)
}
}
diff --git a/app/src/main/java/com/hfut/schedule/ui/activity/home/cube/main/SettingsUI.kt b/app/src/main/java/com/hfut/schedule/ui/activity/home/cube/main/SettingsUI.kt
index a520431..d8e72e1 100644
--- a/app/src/main/java/com/hfut/schedule/ui/activity/home/cube/main/SettingsUI.kt
+++ b/app/src/main/java/com/hfut/schedule/ui/activity/home/cube/main/SettingsUI.kt
@@ -39,6 +39,7 @@ import com.hfut.schedule.ui.activity.home.cube.items.NavUIs.NetWorkScreen
import com.hfut.schedule.ui.activity.home.cube.items.main.Screen
import com.hfut.schedule.ui.activity.home.cube.items.NavUIs.UIScreen
import com.hfut.schedule.ui.activity.home.cube.items.subitems.TEST
+import com.hfut.schedule.ui.utils.NavigateManager
@SuppressLint("SuspiciousIndentation", "UnusedMaterial3ScaffoldPaddingParameter")
@OptIn(ExperimentalMaterial3Api::class)
@@ -73,10 +74,10 @@ fun SettingsScreen(vm : NetWorkViewModel
navController = navController,
startDestination = Screen.HomeScreen.route,
enterTransition = {
- scaleIn(animationSpec = tween(durationMillis = animation)) + expandVertically(expandFrom = Alignment.CenterVertically,animationSpec = tween(durationMillis = animation))
+ NavigateManager.centerAnimation.enter
},
exitTransition = {
- scaleOut(animationSpec = tween(durationMillis = animation)) + shrinkVertically(shrinkTowards = Alignment.CenterVertically,animationSpec = tween(durationMillis = animation))
+ NavigateManager.centerAnimation.exit
}
) {
diff --git a/app/src/main/java/com/hfut/schedule/ui/activity/home/main/login/LoginSuccessBar.kt b/app/src/main/java/com/hfut/schedule/ui/activity/home/main/login/LoginSuccessBar.kt
index 45d2e6c..4c8cb45 100644
--- a/app/src/main/java/com/hfut/schedule/ui/activity/home/main/login/LoginSuccessBar.kt
+++ b/app/src/main/java/com/hfut/schedule/ui/activity/home/main/login/LoginSuccessBar.kt
@@ -38,6 +38,8 @@ import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@@ -67,6 +69,7 @@ import com.hfut.schedule.ui.activity.home.cube.main.SettingsScreen
import com.hfut.schedule.ui.activity.home.focus.main.TodayScreen
import com.hfut.schedule.logic.enums.BottomBarItems.*
import com.hfut.schedule.logic.utils.APPVersion
+import com.hfut.schedule.logic.utils.DataStoreManager
import com.hfut.schedule.ui.activity.home.calendar.communtiy.CourseDetailApi
import com.hfut.schedule.ui.activity.home.calendar.jxglstu.CalendarScreen
import com.hfut.schedule.ui.activity.home.main.saved.texts
@@ -84,6 +87,9 @@ import com.hfut.schedule.ui.activity.home.search.functions.notifications.getNoti
import com.hfut.schedule.ui.activity.home.search.functions.totalCourse.CourseTotalForApi
import com.hfut.schedule.ui.activity.home.search.functions.webLab.LabUI
import com.hfut.schedule.ui.activity.home.search.main.SearchFuncs
+import com.hfut.schedule.ui.utils.NavigateManager
+import com.hfut.schedule.ui.utils.NavigateManager.currentPage
+import com.hfut.schedule.ui.utils.NavigateManager.turnToAndClear
import com.hfut.schedule.ui.utils.components.CustomTabRow
import com.hfut.schedule.ui.utils.components.DividerText
import com.hfut.schedule.ui.utils.components.DividerTextExpandedWith
@@ -113,7 +119,7 @@ fun SuccessUI(vm : NetWorkViewModel, grade : String, vm2 : LoginViewModel, vmUI
val navController = rememberNavController()
var isEnabled by remember { mutableStateOf(false) }
var showlable by remember { mutableStateOf(switch) }
- var bottomBarItems by remember { mutableStateOf(COURSES) }
+
val hazeState = remember { HazeState() }
var showBadge by remember { mutableStateOf(false) }
if (getUpdates().version != APPVersion.getVersionName()) showBadge = true
@@ -184,9 +190,12 @@ fun SuccessUI(vm : NetWorkViewModel, grade : String, vm2 : LoginViewModel, vmUI
}
}
+
+
+
var swapUI by remember { mutableStateOf(JXGLSTU) }
var isFriend by remember { mutableStateOf(false) }
-
+ var bottomBarItems by remember { mutableStateOf(COURSES) }
val sheetState_multi = rememberModalBottomSheetState(skipPartiallyExpanded = true)
var showBottomSheet_multi by remember { mutableStateOf(false) }
if (showBottomSheet_multi) {
@@ -212,8 +221,14 @@ fun SuccessUI(vm : NetWorkViewModel, grade : String, vm2 : LoginViewModel, vmUI
var today by remember { mutableStateOf(LocalDate.now()) }
- var searchText by remember { mutableStateOf("") }
+ var searchText by remember { mutableStateOf("") }
+ val currentAnimationIndex by DataStoreManager.animationTypeFlow.collectAsState(initial = 0)
+ if(currentAnimationIndex == 2) {
+ LaunchedEffect(bottomBarItems) {
+ currentPage = bottomBarItems.page
+ }
+ }
Scaffold(
modifier = Modifier.fillMaxSize(),
@@ -341,18 +356,14 @@ fun SuccessUI(vm : NetWorkViewModel, grade : String, vm2 : LoginViewModel, vmUI
enabled = isEnabled,
onClick = {
saveString("tip","0000")
- if(item == items[0]) bottomBarItems = COURSES
- if(item == items[1]) bottomBarItems = FOCUS
- if(item == items[2]) bottomBarItems = SEARCH
- if(item == items[3]) bottomBarItems = SETTINGS
+ when(item) {
+ items[0] -> bottomBarItems = COURSES
+ items[1] -> bottomBarItems = FOCUS
+ items[2] -> bottomBarItems = SEARCH
+ items[3] -> bottomBarItems = SETTINGS
+ }
if (!selected) {
- navController.navigate(route) {
- popUpTo(navController.graph.startDestinationId) {
- saveState = true
- }
- launchSingleTop = true
- restoreState = true
- }
+ turnToAndClear(navController,route)
}
},
label = { Text(text = item.label) },
@@ -370,16 +381,12 @@ fun SuccessUI(vm : NetWorkViewModel, grade : String, vm2 : LoginViewModel, vmUI
}
}
) { innerPadding ->
+ val animation = NavigateManager.getAnimationType(currentAnimationIndex,bottomBarItems.page)
+
NavHost(navController = navController,
startDestination = COURSES.name,
- enterTransition = {
- scaleIn(animationSpec = tween(durationMillis = animation)) +
- expandVertically(expandFrom = Alignment.Top,animationSpec = tween(durationMillis = animation))
- },
- exitTransition = {
- scaleOut(animationSpec = tween(durationMillis = animation)) +
- shrinkVertically(shrinkTowards = Alignment.Top,animationSpec = tween(durationMillis = animation))
- },
+ enterTransition = { animation.enter },
+ exitTransition = { animation.exit },
modifier = Modifier
.haze(
state = hazeState,
diff --git a/app/src/main/java/com/hfut/schedule/ui/activity/home/main/saved/SavedUIBar.kt b/app/src/main/java/com/hfut/schedule/ui/activity/home/main/saved/SavedUIBar.kt
index 7bfc997..591c696 100644
--- a/app/src/main/java/com/hfut/schedule/ui/activity/home/main/saved/SavedUIBar.kt
+++ b/app/src/main/java/com/hfut/schedule/ui/activity/home/main/saved/SavedUIBar.kt
@@ -42,6 +42,8 @@ import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@@ -69,6 +71,7 @@ import com.hfut.schedule.logic.enums.BottomBarItems.*
import com.hfut.schedule.logic.beans.NavigationBarItemData
import com.hfut.schedule.logic.utils.APPVersion
import com.hfut.schedule.logic.utils.AndroidVersion.canBlur
+import com.hfut.schedule.logic.utils.DataStoreManager
import com.hfut.schedule.logic.utils.DateTimeManager
import com.hfut.schedule.logic.utils.DateTimeManager.Benweeks
import com.hfut.schedule.logic.utils.DateTimeManager.Date_MM_dd
@@ -92,6 +95,11 @@ import com.hfut.schedule.ui.activity.home.search.functions.totalCourse.CourseTot
import com.hfut.schedule.ui.activity.home.search.functions.webLab.LabUI
import com.hfut.schedule.ui.activity.home.search.main.SearchFuncs
import com.hfut.schedule.ui.activity.home.search.main.SearchScreen
+import com.hfut.schedule.ui.activity.login.First
+import com.hfut.schedule.ui.utils.NavigateManager
+import com.hfut.schedule.ui.utils.NavigateManager.ANIMATION_SPEED
+import com.hfut.schedule.ui.utils.NavigateManager.currentPage
+import com.hfut.schedule.ui.utils.NavigateManager.turnToAndClear
import com.hfut.schedule.ui.utils.components.CustomTabRow
import com.hfut.schedule.ui.utils.components.DividerText
import com.hfut.schedule.ui.utils.components.DividerTextExpandedWith
@@ -124,7 +132,7 @@ fun NoNetWork(vm : NetWorkViewModel, vm2 : LoginViewModel, vmUI : UIViewModel) {
var showlable by remember { mutableStateOf(switch) }
val hazeState = remember { HazeState() }
- var bottomBarItems by remember { mutableStateOf(FOCUS) }
+// var bottomBarItems by remember { mutableStateOf(FOCUS) }
var showBadge by remember { mutableStateOf(false) }
if (getUpdates().version != APPVersion.getVersionName()) showBadge = true
val switchblur = prefs.getBoolean("SWITCHBLUR", canBlur)
@@ -134,13 +142,19 @@ fun NoNetWork(vm : NetWorkViewModel, vm2 : LoginViewModel, vmUI : UIViewModel) {
//if (savenum != getnum) showBadge2 = true
val animation by remember { mutableStateOf(prefs.getInt("ANIMATION", MyApplication.Animation)) }
+
+
//Log.d("动画",animation.toString())
//判定是否以聚焦作为第一页
- val first : String = when (prefs.getBoolean("SWITCHFOCUS",true)) {
- true -> FOCUS.name
- false -> COURSES.name
+ val first = when (prefs.getBoolean("SWITCHFOCUS",true)) {
+ true -> FOCUS
+ false -> COURSES
}
+ // 按下底栏按钮后,要准备去的导航
+ var targetPage by remember { mutableStateOf(first) }
+ // 记录上一个
+
var showAll by remember { mutableStateOf(false) }
var findCourse by remember { mutableStateOf(false) }
@@ -210,7 +224,7 @@ fun NoNetWork(vm : NetWorkViewModel, vm2 : LoginViewModel, vmUI : UIViewModel) {
}
}
}
-
+ val currentAnimationIndex by DataStoreManager.animationTypeFlow.collectAsState(initial = 0)
if (showBottomSheet_multi) {
ModalBottomSheet(onDismissRequest = { showBottomSheet_multi = false }, sheetState = sheetState_multi, modifier = Modifier,
@@ -250,6 +264,14 @@ fun NoNetWork(vm : NetWorkViewModel, vm2 : LoginViewModel, vmUI : UIViewModel) {
var showSearch by remember { mutableStateOf(false) }
vmUI.findNewCourse.observeForever(Observer)
if(findCourse) vmUI.findNewCourse.removeObserver(Observer)
+
+ // 保存上一页页码 用于决定左右动画
+ if(currentAnimationIndex == 2) {
+ LaunchedEffect(targetPage) {
+ currentPage = targetPage.page
+ }
+ }
+
Scaffold(
modifier = Modifier.fillMaxSize(),
//.blur(blurRadius, BlurredEdgeTreatment.Unbounded),
@@ -264,8 +286,8 @@ fun NoNetWork(vm : NetWorkViewModel, vm2 : LoginViewModel, vmUI : UIViewModel) {
),
title = {
- if(bottomBarItems != SEARCH) {
- ScrollText(texts(bottomBarItems))
+ if(targetPage != SEARCH) {
+ ScrollText(texts(targetPage))
} else {
if(!showSearch) {
ScrollText(texts(SEARCH))
@@ -277,7 +299,7 @@ fun NoNetWork(vm : NetWorkViewModel, vm2 : LoginViewModel, vmUI : UIViewModel) {
}
},
actions = {
- when(bottomBarItems){
+ when(targetPage){
COURSES -> {
CourseTotalForApi(vm=vm, isIconOrText = true)
IconButton(onClick = {
@@ -327,7 +349,7 @@ fun NoNetWork(vm : NetWorkViewModel, vm2 : LoginViewModel, vmUI : UIViewModel) {
// if(bottomBarItems != FOCUS)
// Divider()
// }
- when(bottomBarItems){
+ when(targetPage){
COURSES -> ScheduleTopDate(showAll,today,blur)
FOCUS -> CustomTabRow(pagerState, titles, blur)
// SEARCH -> SearchFuncs()
@@ -367,19 +389,14 @@ fun NoNetWork(vm : NetWorkViewModel, vm2 : LoginViewModel, vmUI : UIViewModel) {
modifier = Modifier.scale(scale.value),
interactionSource = interactionSource,
onClick = {
- if(item == items[0]) bottomBarItems = COURSES
- if(item == items[1]) bottomBarItems = FOCUS
- if(item == items[2]) bottomBarItems = SEARCH
- if(item == items[3]) bottomBarItems = SETTINGS
- // atEnd = !atEnd
+ when(item) {
+ items[0] -> targetPage = COURSES
+ items[1] -> targetPage = FOCUS
+ items[2] -> targetPage = SEARCH
+ items[3] -> targetPage = SETTINGS
+ }
if (!selected) {
- navController.navigate(route) {
- popUpTo(navController.graph.startDestinationId) {
- saveState = true
- }
- launchSingleTop = true
- restoreState = true
- }
+ turnToAndClear(navController,route)
}
},
label = { Text(text = item.label) },
@@ -397,23 +414,15 @@ fun NoNetWork(vm : NetWorkViewModel, vm2 : LoginViewModel, vmUI : UIViewModel) {
}
}
) { innerPadding ->
+ val animation = NavigateManager.getAnimationType(currentAnimationIndex,targetPage.page)
NavHost(
navController = navController,
- startDestination = first,
- enterTransition = {
- // fadeIn(animationSpec = tween(durationMillis = animation)) +
- scaleIn(animationSpec = tween(durationMillis = animation)) +
- expandVertically(expandFrom = Alignment.Top,animationSpec = tween(durationMillis = animation))
- },
- exitTransition = {
- // fadeOut(animationSpec = tween(durationMillis = animation)) +
- scaleOut(animationSpec = tween(durationMillis = animation)) +
- shrinkVertically(shrinkTowards = Alignment.Top,animationSpec = tween(durationMillis = animation))
- },
+ startDestination = first.name,
+ enterTransition = { animation.enter },
+ exitTransition = { animation.exit },
modifier = Modifier
.haze(
state = hazeState,
- //backgroundColor = MaterialTheme.colorScheme.surface,
)) {
composable(COURSES.name) {
Scaffold(modifier = Modifier.pointerInput(Unit) {
diff --git a/app/src/main/java/com/hfut/schedule/ui/activity/login/LoginUI.kt b/app/src/main/java/com/hfut/schedule/ui/activity/login/LoginUI.kt
index ad19444..f216892 100644
--- a/app/src/main/java/com/hfut/schedule/ui/activity/login/LoginUI.kt
+++ b/app/src/main/java/com/hfut/schedule/ui/activity/login/LoginUI.kt
@@ -16,8 +16,12 @@ import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
+import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
+import androidx.compose.animation.scaleIn
+import androidx.compose.animation.scaleOut
+import androidx.compose.animation.shrinkVertically
import androidx.compose.animation.with
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsPressedAsState
@@ -77,6 +81,9 @@ import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
+import androidx.navigation.compose.NavHost
+import androidx.navigation.compose.composable
+import androidx.navigation.compose.rememberNavController
import com.hfut.schedule.App.MyApplication
import com.hfut.schedule.R
import com.hfut.schedule.viewmodel.LoginViewModel
@@ -90,6 +97,7 @@ import com.hfut.schedule.logic.utils.SharePrefs.saveString
import com.hfut.schedule.logic.utils.SharePrefs.prefs
import com.hfut.schedule.logic.utils.Starter.noLogin
import com.hfut.schedule.ui.activity.home.cube.items.main.FirstCube
+import com.hfut.schedule.ui.utils.NavigateManager.ANIMATION_SPEED
import com.hfut.schedule.ui.utils.components.MyToast
import com.hfut.schedule.ui.utils.style.Round
import kotlinx.coroutines.CoroutineScope
@@ -186,8 +194,17 @@ fun SavedClick() {
} else noLogin()
}
+//
+//@Composable
+//fun FirstUI(vm: LoginViewModel) {
+//
+//}
+
+enum class First {
+ HOME,USE_AGREEMENT
+}
+
-@RequiresApi(Build.VERSION_CODES.O)
@SuppressLint("SuspiciousIndentation")
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -201,6 +218,7 @@ fun LoginUI(vm : LoginViewModel) {
// val hazeState = remember { HazeState() }
+
if (showBottomSheet) {
ModalBottomSheet(
onDismissRequest = {
@@ -279,7 +297,6 @@ fun LoginUI(vm : LoginViewModel) {
.padding(innerPadding)
.fillMaxSize()) {
TwoTextField(vm)
- //Text(text = "欢迎使用")
}
}
}
@@ -288,7 +305,7 @@ fun LoginUI(vm : LoginViewModel) {
@Composable
fun AnimatedWelcomeScreen() {
val welcomeTexts = listOf(
- "你好", "(。・ω・)ノ゙", "欢迎使用", "ヾ(*゚▽゚)ノ", "Hello","(^-^*)", "Hola", "U。・x・)ノ", "Bonjour","\(≧▽≦)/"
+ "你好", "(。・ω・)ノ゙", "欢迎使用", "ヾ(*゚▽゚)ノ","Hello", "*。٩(ˊωˋ*)و✧*。","Hola", "(⸝•̀֊•́⸝)", "Bonjour","\(≧▽≦)/"
)
var currentIndex by remember { mutableStateOf(0) }
LaunchedEffect(Unit) {
diff --git a/app/src/main/java/com/hfut/schedule/ui/activity/login/UssAgreement.kt b/app/src/main/java/com/hfut/schedule/ui/activity/login/UssAgreement.kt
new file mode 100644
index 0000000..590e539
--- /dev/null
+++ b/app/src/main/java/com/hfut/schedule/ui/activity/login/UssAgreement.kt
@@ -0,0 +1,187 @@
+package com.hfut.schedule.ui.activity.login
+
+import android.app.Activity
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.material3.Button
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.FilledTonalButton
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.LargeTopAppBar
+import androidx.compose.material3.ListItem
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.material3.TopAppBarDefaults
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.unit.dp
+import androidx.navigation.NavHostController
+import com.hfut.schedule.R
+import com.hfut.schedule.logic.utils.AndroidVersion.canBlur
+import com.hfut.schedule.logic.utils.SharePrefs
+import com.hfut.schedule.logic.utils.SharePrefs.prefs
+import com.hfut.schedule.ui.utils.NavigateManager
+import com.hfut.schedule.ui.utils.components.MyToast
+import com.hfut.schedule.ui.utils.style.bottomBarBlur
+import com.hfut.schedule.ui.utils.style.topBarBlur
+import dev.chrisbanes.haze.HazeState
+import dev.chrisbanes.haze.haze
+import nl.dionsegijn.konfetti.compose.KonfettiView
+import nl.dionsegijn.konfetti.core.Party
+import nl.dionsegijn.konfetti.core.Position
+import nl.dionsegijn.konfetti.core.emitter.Emitter
+import java.util.concurrent.TimeUnit
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+//@Preview
+fun UseAgreementUI(navController : NavHostController) {
+ val hazeState = remember { HazeState() }
+ val switchblur = prefs.getBoolean("SWITCHBLUR", canBlur)
+ var blur by remember { mutableStateOf(switchblur) }
+
+
+ val argeements = listOf(
+ "本应用所使用权限为:网络、日历(用于向日历写入聚焦日程)、存储(用于导入导出课程表文件)、相机(用于洗浴扫码),均由用户自由决定是否授予",
+ "本应用已在Github开源,F-Droid上架,无任何盈利、广告、恶意等行为",
+ "本应用不代表学校官方,如侵害到您的权益请联系邮件zsh0908@outlook.com",
+ "本应用推荐但不限于合肥工业大学宣城校区在校生使用,不对未登录用户做强制要求,可通过游客模式进入",
+ "本应用存在开发者自己的服务端,会收集一些不敏感的数据帮助改善使用体验,开发者承诺不会泄露数据,且用户可自由选择开启与否",
+ "开发者只负责分发由自己签名的版本(签名为O=Chiu xaH ST=Anhui L=Xuancheng),其他签名版本不对此负责",
+ "最后编辑于 2025-01-29 22:11 v1"
+ )
+ val developerInfo = mapOf(
+ "contact" to "zsh0908@outlook.com",
+ "github" to "Chiu-xaH",
+ "profile" to "一名热爱安卓的开发者,宣城校区23级计算机科学与技术专业(转)本科生"
+ )
+ val context = LocalContext.current
+
+ val partyTopStart = Party(
+ emitter = Emitter(duration = 1, TimeUnit.SECONDS).perSecond(30),
+ position = Position.Relative(0.0,0.0)
+ )
+ val partyTopEnd = Party(
+ emitter = Emitter(duration = 1, TimeUnit.SECONDS).perSecond(30),
+ position = Position.Relative(1.0,0.0)
+ )
+ val partyBottomStart = Party(
+ emitter = Emitter(duration = 1, TimeUnit.SECONDS).perSecond(30),
+ position = Position.Relative(0.0,1.0)
+ )
+ val partyBottomEnd = Party(
+ emitter = Emitter(duration = 1, TimeUnit.SECONDS).perSecond(30),
+ position = Position.Relative(1.0,1.0)
+ )
+
+ Box(modifier = Modifier.fillMaxSize()) {
+ KonfettiView(
+ modifier = Modifier.fillMaxSize(),
+ parties = listOf(partyTopStart,partyTopEnd,partyBottomStart,partyBottomEnd),
+ )
+ androidx.compose.material3.Scaffold(
+ topBar = {
+ LargeTopAppBar(
+ colors = TopAppBarDefaults.mediumTopAppBarColors(
+ containerColor = Color.Transparent,
+ titleContentColor = MaterialTheme.colorScheme.primary,
+ ),
+ title = {
+ Box(modifier = Modifier.fillMaxWidth()) {
+ Text(
+ text = "用户协议",
+ modifier = Modifier.fillMaxWidth(),
+ textAlign = TextAlign.Center,
+ //style = MaterialTheme.typography.titleLarge
+ )
+ }
+ },
+ actions = {
+ // Row {
+ IconButton(onClick = {
+ (context as? Activity)?.finish()
+ }) {
+ Icon(
+ painterResource(id = R.drawable.close),
+ contentDescription = "",
+ tint = MaterialTheme.colorScheme.primary
+ )
+ }
+ // Text(text = " ")
+ /// }
+
+ },
+ navigationIcon = {
+ AnimatedWelcomeScreen()
+ },
+ modifier = Modifier.topBarBlur(hazeState,blur)
+ )
+ },
+ bottomBar = {
+ Box(modifier = Modifier.bottomBarBlur(hazeState, blur)) {
+ Row(modifier = Modifier.padding(15.dp),horizontalArrangement = Arrangement.Center) {
+ Button(
+ onClick = {
+ SharePrefs.saveBoolean("canUse", default = false, save = true)
+ NavigateManager.turnToAndClear(navController, First.HOME.name)
+ },
+ modifier = Modifier
+ .fillMaxWidth()
+ .weight(.5f)
+ ) {
+ Text("同意")
+ }
+ Spacer(modifier = Modifier.width(15.dp))
+ FilledTonalButton(
+ onClick = {
+ MyToast("已关闭APP")
+ (context as Activity).finish()
+ },
+ modifier = Modifier
+ .fillMaxWidth()
+ .weight(.5f)
+ ) {
+ SharePrefs.saveBoolean("canUse", default = false, save = false)
+ Text("拒绝")
+ }
+ }
+ }
+ },
+ ) { innerPadding ->
+ Column(
+ modifier = Modifier
+ .fillMaxSize().haze(hazeState)
+ ) {
+ LazyColumn {
+ item { Spacer(modifier = Modifier.height(innerPadding.calculateTopPadding())) }
+ items(argeements.size) { index ->
+ val item = argeements[index]
+ ListItem(
+ headlineContent = { Text(item) },
+ leadingContent = { Text((index+1).toString()) }
+ )
+ }
+ item { Spacer(modifier = Modifier.height(innerPadding.calculateBottomPadding())) }
+ }
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/hfut/schedule/ui/activity/news/main/NewsActivityUI.kt b/app/src/main/java/com/hfut/schedule/ui/activity/news/main/NewsActivityUI.kt
index 461c4f7..a18f4fd 100644
--- a/app/src/main/java/com/hfut/schedule/ui/activity/news/main/NewsActivityUI.kt
+++ b/app/src/main/java/com/hfut/schedule/ui/activity/news/main/NewsActivityUI.kt
@@ -38,7 +38,6 @@ import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.AssistChip
import androidx.compose.material3.BadgedBox
-import androidx.compose.material3.CircularProgressIndicator
import com.hfut.schedule.ui.utils.components.LoadingUI
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExtendedFloatingActionButton
@@ -55,6 +54,8 @@ import androidx.compose.material3.TextFieldDefaults
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@@ -76,12 +77,17 @@ import com.hfut.schedule.viewmodel.NetWorkViewModel
import com.hfut.schedule.logic.enums.NewsBarItems
import com.hfut.schedule.logic.beans.NavigationBarItemData
import com.hfut.schedule.logic.utils.AndroidVersion
+import com.hfut.schedule.logic.utils.DataStoreManager
import com.hfut.schedule.logic.utils.Encrypt
import com.hfut.schedule.logic.utils.SharePrefs
-import com.hfut.schedule.ui.activity.card.function.main.turnToBottomBar
+//import com.hfut.schedule.ui.activity.card.function.main.turnToBottomBar
import com.hfut.schedule.ui.activity.news.home.NewsItem
import com.hfut.schedule.ui.activity.news.departments.SchoolsUI
import com.hfut.schedule.ui.activity.news.xuancheng.XuanquNewsUI
+import com.hfut.schedule.ui.utils.NavigateManager
+import com.hfut.schedule.ui.utils.NavigateManager.currentPage
+import com.hfut.schedule.ui.utils.NavigateManager.turnTo
+import com.hfut.schedule.ui.utils.NavigateManager.turnToAndClear
import com.hfut.schedule.ui.utils.components.MyToast
import com.hfut.schedule.ui.utils.style.bottomBarBlur
import com.hfut.schedule.ui.utils.style.topBarBlur
@@ -104,7 +110,18 @@ fun NewsActivityUI(vm: NetWorkViewModel) {
val switchblur = SharePrefs.prefs.getBoolean("SWITCHBLUR", AndroidVersion.canBlur)
val blur by remember { mutableStateOf(switchblur) }
val hazeState = remember { HazeState() }
- var bottomBarItems by remember { mutableStateOf(NewsBarItems.News) }
+// var bottomBarItems by remember { mutableStateOf(NewsBarItems.News) }
+ val currentAnimationIndex by DataStoreManager.animationTypeFlow.collectAsState(initial = 0)
+ var targetPage by remember { mutableStateOf(NewsBarItems.News) }
+ // 保存上一页页码 用于决定左右动画
+ if(currentAnimationIndex == 2) {
+ LaunchedEffect(targetPage) {
+ currentPage = targetPage.page
+ }
+ }
+
+
+
Scaffold(
modifier = Modifier.fillMaxSize(),
topBar = {
@@ -117,7 +134,7 @@ fun NewsActivityUI(vm: NetWorkViewModel) {
),
title = { Text("通知公告") },
actions = {
- if(bottomBarItems == NewsBarItems.XuanCheng) {
+ if(targetPage == NewsBarItems.XuanCheng) {
IconButton(onClick = {
MyToast("正在开发")
}) {
@@ -173,13 +190,15 @@ fun NewsActivityUI(vm: NetWorkViewModel) {
interactionSource = interactionSource,
onClick = {
// atEnd = !atEnd
- bottomBarItems = when(item) {
- items[0] -> NewsBarItems.News
- items[1] -> NewsBarItems.XuanCheng
- items[2] -> NewsBarItems.School
- else -> NewsBarItems.News
+ if(currentAnimationIndex == 2) {
+ targetPage = when(item) {
+ items[0] -> NewsBarItems.News
+ items[1] -> NewsBarItems.XuanCheng
+ items[2] -> NewsBarItems.School
+ else -> NewsBarItems.News
+ }
}
- if (!selected) { turnToBottomBar(navController, route) }
+ if (!selected) { turnToAndClear(navController, route) }
},
label = { Text(text = item.label) },
icon = {
@@ -192,16 +211,13 @@ fun NewsActivityUI(vm: NetWorkViewModel) {
}
) {innerPadding ->
+
+ val animation = NavigateManager.getAnimationType(currentAnimationIndex,targetPage.page)
+
NavHost(navController = navController,
startDestination = NewsBarItems.News.name,
- enterTransition = {
- scaleIn(animationSpec = tween(durationMillis = animation)) +
- expandVertically(expandFrom = Alignment.Top,animationSpec = tween(durationMillis = animation))
- },
- exitTransition = {
- scaleOut(animationSpec = tween(durationMillis = animation)) +
- shrinkVertically(shrinkTowards = Alignment.Top,animationSpec = tween(durationMillis = animation))
- },
+ enterTransition = { animation.enter },
+ exitTransition = { animation.exit },
modifier = Modifier.haze(state = hazeState)) {
composable(NewsBarItems.News.name) {
Scaffold {
diff --git a/app/src/main/java/com/hfut/schedule/ui/activity/nologin/NoLoginUI.kt b/app/src/main/java/com/hfut/schedule/ui/activity/nologin/NoLoginUI.kt
index 5f56a4c..f1f2fa4 100644
--- a/app/src/main/java/com/hfut/schedule/ui/activity/nologin/NoLoginUI.kt
+++ b/app/src/main/java/com/hfut/schedule/ui/activity/nologin/NoLoginUI.kt
@@ -36,6 +36,8 @@ import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@@ -56,6 +58,7 @@ import com.hfut.schedule.logic.beans.NavigationBarItemData
import com.hfut.schedule.logic.enums.BottomBarItems
import com.hfut.schedule.logic.utils.APPVersion
import com.hfut.schedule.logic.utils.AndroidVersion
+import com.hfut.schedule.logic.utils.DataStoreManager
import com.hfut.schedule.logic.utils.SharePrefs
import com.hfut.schedule.logic.utils.Starter
import com.hfut.schedule.ui.activity.home.cube.items.subitems.MyAPIItem
@@ -66,6 +69,9 @@ import com.hfut.schedule.ui.activity.home.search.functions.notifications.Notific
import com.hfut.schedule.ui.activity.home.search.functions.notifications.getNotifications
import com.hfut.schedule.ui.activity.home.search.functions.webLab.LabUI
import com.hfut.schedule.ui.activity.home.search.main.SearchFuncs
+import com.hfut.schedule.ui.utils.NavigateManager
+import com.hfut.schedule.ui.utils.NavigateManager.currentPage
+import com.hfut.schedule.ui.utils.NavigateManager.turnToAndClear
import com.hfut.schedule.ui.utils.components.CustomTabRow
import com.hfut.schedule.ui.utils.components.DividerText
import com.hfut.schedule.ui.utils.components.DividerTextExpandedWith
@@ -93,7 +99,6 @@ fun NoLoginUI(vm : NetWorkViewModel,vm2 : LoginViewModel,vmUI : UIViewModel) {
var showlable by remember { mutableStateOf(switch) }
val hazeState = remember { HazeState() }
- var bottomBarItems by remember { mutableStateOf(BottomBarItems.SEARCH) }
var showBadge by remember { mutableStateOf(false) }
if (getUpdates().version != APPVersion.getVersionName()) showBadge = true
val switchblur = SharePrefs.prefs.getBoolean("SWITCHBLUR", AndroidVersion.canBlur)
@@ -101,8 +106,9 @@ fun NoLoginUI(vm : NetWorkViewModel,vm2 : LoginViewModel,vmUI : UIViewModel) {
val animation by remember { mutableStateOf(SharePrefs.prefs.getInt("ANIMATION", MyApplication.Animation)) }
- val first : String = BottomBarItems.SEARCH.name
+ val first = BottomBarItems.SEARCH
+ var bottomBarItems by remember { mutableStateOf(first) }
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
@@ -112,6 +118,13 @@ fun NoLoginUI(vm : NetWorkViewModel,vm2 : LoginViewModel,vmUI : UIViewModel) {
CoroutineScope(Job()).launch { NetWorkUpdateNoLogin(vm2) }
+ val currentAnimationIndex by DataStoreManager.animationTypeFlow.collectAsState(initial = 0)
+// var targetPage by remember { mutableStateOf(FixBarItems.Fix) }
+ // 保存上一页页码 用于决定左右动画
+ LaunchedEffect(bottomBarItems) {
+ currentPage = bottomBarItems.page
+ }
+
if (showBottomSheet) {
@@ -273,13 +286,7 @@ fun NoLoginUI(vm : NetWorkViewModel,vm2 : LoginViewModel,vmUI : UIViewModel) {
if(item == items[2]) bottomBarItems = BottomBarItems.SETTINGS
// atEnd = !atEnd
if (!selected) {
- navController.navigate(route) {
- popUpTo(navController.graph.startDestinationId) {
- saveState = true
- }
- launchSingleTop = true
- restoreState = true
- }
+ turnToAndClear(navController,route)
}
},
label = { Text(text = item.label) },
@@ -297,19 +304,13 @@ fun NoLoginUI(vm : NetWorkViewModel,vm2 : LoginViewModel,vmUI : UIViewModel) {
}
}
) { innerPadding ->
+ val animation = NavigateManager.getAnimationType(currentAnimationIndex,bottomBarItems.page)
+
NavHost(
navController = navController,
- startDestination = first,
- enterTransition = {
- // fadeIn(animationSpec = tween(durationMillis = animation)) +
- scaleIn(animationSpec = tween(durationMillis = animation)) +
- expandVertically(expandFrom = Alignment.Top,animationSpec = tween(durationMillis = animation))
- },
- exitTransition = {
- // fadeOut(animationSpec = tween(durationMillis = animation)) +
- scaleOut(animationSpec = tween(durationMillis = animation)) +
- shrinkVertically(shrinkTowards = Alignment.Top,animationSpec = tween(durationMillis = animation))
- },
+ startDestination = first.name,
+ enterTransition = { animation.enter },
+ exitTransition = { animation.exit },
modifier = Modifier
.haze(
state = hazeState,
diff --git a/app/src/main/java/com/hfut/schedule/ui/activity/shower/main/ShowerGuaguaUI.kt b/app/src/main/java/com/hfut/schedule/ui/activity/shower/main/ShowerGuaguaUI.kt
index 35eb1ff..ed33f16 100644
--- a/app/src/main/java/com/hfut/schedule/ui/activity/shower/main/ShowerGuaguaUI.kt
+++ b/app/src/main/java/com/hfut/schedule/ui/activity/shower/main/ShowerGuaguaUI.kt
@@ -28,9 +28,12 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.scale
@@ -47,11 +50,16 @@ import com.hfut.schedule.viewmodel.GuaGuaViewModel
import com.hfut.schedule.logic.enums.ShowerBarItems
import com.hfut.schedule.logic.beans.NavigationBarItemData
import com.hfut.schedule.logic.utils.AndroidVersion
+import com.hfut.schedule.logic.utils.DataStoreManager
import com.hfut.schedule.logic.utils.SharePrefs
-import com.hfut.schedule.ui.activity.card.function.main.turnToBottomBar
+//import com.hfut.schedule.ui.activity.card.function.main.turnToBottomBar
import com.hfut.schedule.ui.activity.shower.bills.GuaguaBills
import com.hfut.schedule.ui.activity.shower.function.GuaGuaSettings
import com.hfut.schedule.ui.activity.shower.home.main.GuaguaStart
+import com.hfut.schedule.ui.utils.NavigateManager
+import com.hfut.schedule.ui.utils.NavigateManager.currentPage
+import com.hfut.schedule.ui.utils.NavigateManager.turnTo
+import com.hfut.schedule.ui.utils.NavigateManager.turnToAndClear
import com.hfut.schedule.ui.utils.style.bottomBarBlur
import com.hfut.schedule.ui.utils.style.topBarBlur
import com.hfut.schedule.viewmodel.NetWorkViewModel
@@ -68,6 +76,17 @@ fun ShowerGuaGua(vm: GuaGuaViewModel,netVm : NetWorkViewModel) {
val switchblur = SharePrefs.prefs.getBoolean("SWITCHBLUR", AndroidVersion.canBlur)
val blur by remember { mutableStateOf(switchblur) }
val hazeState = remember { HazeState() }
+
+ val currentAnimationIndex by DataStoreManager.animationTypeFlow.collectAsState(initial = 0)
+ var targetPage by remember { mutableStateOf(ShowerBarItems.HOME) }
+ // 保存上一页页码 用于决定左右动画
+ if(currentAnimationIndex == 2) {
+ LaunchedEffect(targetPage) {
+ currentPage = targetPage.page
+ }
+ }
+
+
Scaffold(
modifier = Modifier.fillMaxSize(),
topBar = {
@@ -129,7 +148,14 @@ fun ShowerGuaGua(vm: GuaGuaViewModel,netVm : NetWorkViewModel) {
interactionSource = interactionSource,
onClick = {
// atEnd = !atEnd
- if (!selected) { turnToBottomBar(navController, route) }
+ if(currentAnimationIndex == 2) {
+ when(item) {
+ items[0] -> targetPage = ShowerBarItems.HOME
+ items[1] -> targetPage = ShowerBarItems.BILLS
+ items[2] -> targetPage = ShowerBarItems.FUNCTION
+ }
+ }
+ if (!selected) { turnToAndClear(navController, route) }
},
label = { Text(text = item.label) },
icon = {
@@ -142,16 +168,12 @@ fun ShowerGuaGua(vm: GuaGuaViewModel,netVm : NetWorkViewModel) {
}
) {innerPadding ->
+ val animation = NavigateManager.getAnimationType(currentAnimationIndex,targetPage.page)
+
NavHost(navController = navController,
startDestination = ShowerBarItems.HOME.name,
- enterTransition = {
- scaleIn(animationSpec = tween(durationMillis = animation)) +
- expandVertically(expandFrom = Alignment.Top,animationSpec = tween(durationMillis = animation))
- },
- exitTransition = {
- scaleOut(animationSpec = tween(durationMillis = animation)) +
- shrinkVertically(shrinkTowards = Alignment.Top,animationSpec = tween(durationMillis = animation))
- },
+ enterTransition = { animation.enter },
+ exitTransition = { animation.exit },
modifier = Modifier
.haze(
state = hazeState,
diff --git a/app/src/main/java/com/hfut/schedule/ui/utils/NavigateManager.kt b/app/src/main/java/com/hfut/schedule/ui/utils/NavigateManager.kt
index cf33ed7..65d1740 100644
--- a/app/src/main/java/com/hfut/schedule/ui/utils/NavigateManager.kt
+++ b/app/src/main/java/com/hfut/schedule/ui/utils/NavigateManager.kt
@@ -1,9 +1,56 @@
package com.hfut.schedule.ui.utils
+//import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.EnterTransition
+import androidx.compose.animation.ExitTransition
+import androidx.compose.animation.core.tween
+import androidx.compose.animation.expandVertically
+import androidx.compose.animation.fadeIn
+import androidx.compose.animation.fadeOut
+import androidx.compose.animation.scaleIn
+import androidx.compose.animation.scaleOut
+import androidx.compose.animation.shrinkVertically
+import androidx.compose.animation.slideInHorizontally
+import androidx.compose.animation.slideOutHorizontally
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.lazy.LazyRow
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.CardDefaults
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.OutlinedCard
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
+import com.hfut.schedule.logic.utils.DataStoreManager
+import com.hfut.schedule.ui.utils.NavigateManager.ANIMATION_SPEED
+import com.hfut.schedule.ui.utils.components.DividerTextExpandedWith
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
object NavigateManager {
- fun turnToBottomBar(navController : NavHostController, route : String) {
+ data class TransferAnimation(val remark : String,val enter : EnterTransition, val exit : ExitTransition)
+
+ fun turnTo(navController : NavHostController, route : String) {
navController.navigate(route) {
popUpTo(navController.graph.startDestinationId) {
saveState = true
@@ -12,4 +59,117 @@ object NavigateManager {
restoreState = true
}
}
-}
\ No newline at end of file
+
+ fun turnToAndClear(navController: NavHostController, route: String) {
+ navController.navigate(route) {
+ popUpTo(navController.graph.startDestinationId) {
+ inclusive = true
+ }
+ launchSingleTop = true
+ restoreState = true
+ }
+ }
+
+ const val ANIMATION_SPEED = 400
+
+ private val enterAnimation1 = scaleIn(animationSpec = tween(durationMillis = ANIMATION_SPEED)) +
+ expandVertically(expandFrom = Alignment.Top,animationSpec = tween(durationMillis = ANIMATION_SPEED))
+ private val exitAnimation1 = scaleOut(animationSpec = tween(durationMillis = ANIMATION_SPEED)) +
+ shrinkVertically(shrinkTowards = Alignment.Top,animationSpec = tween(durationMillis = ANIMATION_SPEED))
+ val upDownAnimation = TransferAnimation("底栏吸附",enterAnimation1, exitAnimation1)
+
+ private val enterAnimation2 = scaleIn(animationSpec = tween(durationMillis = ANIMATION_SPEED)) +
+ expandVertically(expandFrom = Alignment.CenterVertically,animationSpec = tween(durationMillis = ANIMATION_SPEED))
+ private val exitAnimation2 = scaleOut(animationSpec = tween(durationMillis = ANIMATION_SPEED)) +
+ shrinkVertically(shrinkTowards = Alignment.CenterVertically,animationSpec = tween(durationMillis = ANIMATION_SPEED))
+ val centerAnimation = TransferAnimation("向中心运动",enterAnimation2, exitAnimation2)
+
+ private val enterAnimationFade = fadeIn(animationSpec = tween(durationMillis = ANIMATION_SPEED))
+
+ private val exitAnimationFade = fadeOut(animationSpec = tween(durationMillis = ANIMATION_SPEED))
+
+ val fadeAnimation = TransferAnimation("淡入淡出", enterAnimationFade, exitAnimationFade)
+
+ private val enterAnimationNull = fadeIn(animationSpec = tween(durationMillis = 0))
+
+ private val exitAnimationNull = fadeOut(animationSpec = tween(durationMillis = 0))
+
+ val nullAnimation = TransferAnimation("无", enterAnimationNull, exitAnimationNull)
+
+
+ // 左右动画
+ private val enterAnimationLeft = slideInHorizontally(
+ initialOffsetX = { fullWidth -> -fullWidth },
+ animationSpec = tween(durationMillis = ANIMATION_SPEED)
+ )
+// + fadeIn(animationSpec = tween(durationMillis = ANIMATION_SPEED))
+
+ private val exitAnimationLeft = slideOutHorizontally(
+ targetOffsetX = { fullWidth -> -fullWidth },
+ animationSpec = tween(durationMillis = ANIMATION_SPEED)
+ )
+// + fadeOut(animationSpec = tween(durationMillis = ANIMATION_SPEED))
+
+ private val leftToRightAnimation = TransferAnimation("从左向右运动", enterAnimationLeft, exitAnimationLeft)
+
+ private val enterAnimationRight = slideInHorizontally(
+ initialOffsetX = { fullWidth -> fullWidth },
+ animationSpec = tween(durationMillis = ANIMATION_SPEED)
+ )
+// + fadeIn(animationSpec = tween(durationMillis = ANIMATION_SPEED))
+
+ private val exitAnimationRight = slideOutHorizontally(
+ targetOffsetX = { fullWidth -> fullWidth },
+ animationSpec = tween(durationMillis = ANIMATION_SPEED)
+ )
+// + fadeOut(animationSpec = tween(durationMillis = ANIMATION_SPEED))
+
+ private val rightToLeftAnimation = TransferAnimation("从右向左运动", enterAnimationRight, exitAnimationRight)
+
+
+
+ var currentPage = 0 // 默认值
+ /*
+ 用法
+ var targetPage by remember { mutableStateOf(first) }
+ // 保存上一页页码 用于决定左右动画
+ LaunchedEffect(targetPage) {
+ currentPage = targetPage.page
+ }
+ onclick按钮赋予点击:
+ when(item) {
+ items[0] -> targetPage = COURSES
+ items[1] -> targetPage = FOCUS
+ items[2] -> targetPage = SEARCH
+ items[3] -> targetPage = SETTINGS
+ }
+ if (!selected) {
+ turnToAndClear(navController,route)
+ }
+ */
+
+ fun getLeftRightAnimation(targetPage : Int) : TransferAnimation {
+ val enterAnimation3 = if (currentPage > targetPage) {
+ leftToRightAnimation.enter
+ } else {
+ rightToLeftAnimation.enter
+ }
+ val exitAnimation3 = if (currentPage > targetPage) {
+ rightToLeftAnimation.exit
+ } else {
+ leftToRightAnimation.exit
+ }
+ return TransferAnimation("左右运动",enterAnimation3, exitAnimation3)
+ }
+
+ fun getAnimationType(index : Int,targetPage: Int = 0) : TransferAnimation {
+ return when(index) {
+ 0 -> upDownAnimation
+ 1 -> centerAnimation
+ 2 -> getLeftRightAnimation(targetPage)
+ 3 -> fadeAnimation
+ 4 -> nullAnimation
+ else -> upDownAnimation
+ }
+ }
+}
diff --git a/app/src/main/java/com/hfut/schedule/ui/utils/components/PartyAnimation.kt b/app/src/main/java/com/hfut/schedule/ui/utils/components/PartyAnimation.kt
new file mode 100644
index 0000000..84f389d
--- /dev/null
+++ b/app/src/main/java/com/hfut/schedule/ui/utils/components/PartyAnimation.kt
@@ -0,0 +1,41 @@
+package com.hfut.schedule.ui.utils.components
+
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.zIndex
+import nl.dionsegijn.konfetti.compose.KonfettiView
+import nl.dionsegijn.konfetti.core.Party
+import nl.dionsegijn.konfetti.core.Position
+import nl.dionsegijn.konfetti.core.emitter.Emitter
+import java.util.concurrent.TimeUnit
+
+@Composable
+fun PartyAnimation(timeSecond : Long = 3,content : @Composable () -> Unit) {
+ val partyTopStart = Party(
+ emitter = Emitter(duration = timeSecond, TimeUnit.SECONDS).perSecond(30),
+ position = Position.Relative(0.0,0.0)
+ )
+ val partyTopEnd = Party(
+ emitter = Emitter(duration = timeSecond, TimeUnit.SECONDS).perSecond(30),
+ position = Position.Relative(1.0,0.0)
+ )
+ val partyBottomStart = Party(
+ emitter = Emitter(duration = timeSecond, TimeUnit.SECONDS).perSecond(30),
+ position = Position.Relative(0.0,1.0)
+ )
+ val partyBottomEnd = Party(
+ emitter = Emitter(duration = timeSecond, TimeUnit.SECONDS).perSecond(30),
+ position = Position.Relative(1.0,1.0)
+ )
+
+ Box(modifier = Modifier.fillMaxSize()) {
+ KonfettiView(
+ modifier = Modifier.fillMaxSize().zIndex(1f),
+ parties = listOf(partyTopStart,partyTopEnd,partyBottomStart,partyBottomEnd),
+ )
+ content()
+ }
+}
+
diff --git "a/markdown/\350\201\232\345\234\250\345\267\245\345\244\247\345\257\222\345\201\207\346\233\264\346\226\260\350\256\241\345\210\222.txt" "b/markdown/\350\201\232\345\234\250\345\267\245\345\244\247\345\257\222\345\201\207\346\233\264\346\226\260\350\256\241\345\210\222.txt"
index 370b170..a4ffb96 100644
--- "a/markdown/\350\201\232\345\234\250\345\267\245\345\244\247\345\257\222\345\201\207\346\233\264\346\226\260\350\256\241\345\210\222.txt"
+++ "b/markdown/\350\201\232\345\234\250\345\267\245\345\244\247\345\257\222\345\201\207\346\233\264\346\226\260\350\256\241\345\210\222.txt"
@@ -1,17 +1,17 @@
聚在工大寒假更新计划
-1.动效(转场)自定义(技术:封装全局Animation和Blur的Manager,OPP思维)(必做)
-3.天气详情、预警聚焦通知(技术:UI设计)
+3.天气详情、预警聚焦通知(技术:UI设计)
6.网费缴纳(必做)
10.图书检索翻页、二级界面、更多信息
11.成绩的两个数据源打通(技术:列表匹配)(必做)
-12.邮箱
13.课程全局收藏体系(技术:数据库)
14.无感教务登录(技术:功能接口设计)
15.培养方案重写(土木分方向)
+1.动效(转场)自定义(技术:封装全局Animation和Blur的Manager,OPP思维)(必做)
+12.邮箱
4.下学期课程汇总图标显示Bug(必做)
7.网、电上弹卡片位置优化(必做)
8.课程汇总右上角按钮间距效果优化(必做)