Skip to content

Commit 50f51d8

Browse files
authored
Merge pull request #84 from aquamarine5/v1.12-quokka-dev
v1.12.2: Support the gesture/pattern signing, performance improvement by `painterIconCache` and bugfixes in general
2 parents 305ec50 + 592a115 commit 50f51d8

25 files changed

+997
-158
lines changed

app/build.gradle

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import org.aquamarine5.brainspark.stackbricks.gradleplugin.PossibleConfigurationPath
2+
13
/*
24
* Copyright (c) 2025, @aquamarine5 (@海蓝色的咕咕鸽). All Rights Reserved.
35
* Author: aquamarine5@163.com (Github: https://github.com/aquamarine5) and Brainspark (previously RenegadeCreation)
@@ -8,16 +10,17 @@ plugins {
810
alias(libs.plugins.android.application)
911
alias(libs.plugins.kotlin.android)
1012
alias(libs.plugins.kotlin.compose)
11-
id("org.aquamarine5.brainspark.stackbricks-gradle-plugin") version "2.2.0"
13+
id("org.aquamarine5.brainspark.stackbricks-gradle-plugin") version "2.2.2"
1214
id("com.google.protobuf") version "0.9.5"
1315
id "io.sentry.android.gradle" version "5.12.1"
14-
id("org.jetbrains.kotlin.plugin.serialization") version "2.2.20"
16+
id("org.jetbrains.kotlin.plugin.serialization") version "2.2.21"
1517
}
1618

1719
stackbricksConfig {
18-
configJsonFilePath = "chaoxingsignfaker_stackbricks_v2_manifest.json"
19-
host = "cdn.aquamarine5.fun"
20-
changelog = "1.12.1版本更新:\n- 1. 支持签到码签到。\n- 2. 优化了验证码处理逻辑。\n- 3. 添加的代签用户现在可以重排序了。\n- 4. 提升了签到速度。\n- 5. 修复了影响签到体验的超级多BUG。\n如果你的版本在1.7.2(250529)以下,那么新版本更新了:\n- 1. 验证码签到\n- 2. 支持签退\n- 3. 触感反馈\n- 4. 修复了崩溃问题\n- 5. 更好看的界面\n如果你的版本在1.4.9(250420)以下,那么新版本还更新了:\n- 1. 支持给其他用户代签\n- 2. 优化了位置签到时的严重卡顿\n\nlovely lonely, 20250920, @aquamarine5 Brainspark."
20+
possibleConfigurationPaths = [
21+
new PossibleConfigurationPath("cdn.aquamarine5.fun", "chaoxingsignfaker_stackbricks_v2_manifest.json")
22+
]
23+
changelog = "1.12版本更新:\n- 1. 支持签到码和图案九宫格签到。\n- 2. 优化了验证码处理逻辑。\n- 3. 添加的代签用户现在可以重排序了。\n- 4. 提升了签到速度。\n- 5. 修复了影响签到体验的超级多BUG。\n如果你的版本在1.7.2(250529)以下,那么新版本更新了:\n- 1. 验证码签到\n- 2. 支持签退\n- 3. 触感反馈\n- 4. 修复了崩溃问题\n- 5. 更好看的界面\n如果你的版本在1.4.9(250420)以下,那么新版本还更新了:\n- 1. 支持给其他用户代签\n- 2. 优化了位置签到时的严重卡顿\n\nlovely lonely, 20250920, @aquamarine5 Brainspark."
2124
requiredManifestVersion2MigrateForceInstall = true
2225
qiniuConfig {
2326
accessKey = project.findProperty("qiniu.accessKey") ?: ""
@@ -29,17 +32,17 @@ stackbricksConfig {
2932
}
3033
android {
3134
namespace = "org.aquamarine5.brainspark.chaoxingsignfaker"
32-
compileSdk = 35
35+
compileSdk = 36
3336

3437
defaultConfig {
3538
ndk {
3639
abiFilters "arm64-v8a"
3740
}
3841
applicationId = "org.aquamarine5.brainspark.chaoxingsignfaker"
3942
minSdk = 26
40-
targetSdk = 35
41-
versionCode = 112021027
42-
versionName = "1.12.1-stable-251027"
43+
targetSdk = 36
44+
versionCode = 112021125
45+
versionName = "1.12.2-stable-251104"
4346

4447
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
4548
}

app/src/main/AndroidManifest.xml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
<application
2424
android:allowBackup="true"
2525
android:dataExtractionRules="@xml/data_extraction_rules"
26-
android:enableOnBackInvokedCallback="true"
2726
android:fullBackupContent="@xml/backup_rules"
2827
android:icon="@mipmap/ic_launcher"
2928
android:label="@string/app_name"
@@ -32,7 +31,6 @@
3231
android:theme="@style/Theme.ChaoxingSignFaker">
3332
<activity
3433
android:name=".MainActivity"
35-
android:enableOnBackInvokedCallback="true"
3634
android:exported="true"
3735
android:theme="@style/Theme.ChaoxingSignFaker">
3836
<intent-filter>
@@ -52,7 +50,6 @@
5250
</activity>
5351
<activity
5452
android:name=".ImportOtherUserActivity"
55-
android:enableOnBackInvokedCallback="true"
5653
android:exported="true"
5754
android:theme="@style/Theme.ChaoxingSignFaker">
5855

app/src/main/java/org/aquamarine5/brainspark/chaoxingsignfaker/MainActivity.kt

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import androidx.compose.animation.fadeIn
2222
import androidx.compose.animation.fadeOut
2323
import androidx.compose.animation.shrinkVertically
2424
import androidx.compose.foundation.background
25+
import androidx.compose.foundation.layout.Box
2526
import androidx.compose.foundation.layout.Column
2627
import androidx.compose.foundation.layout.Spacer
2728
import androidx.compose.foundation.layout.fillMaxSize
@@ -45,13 +46,15 @@ import androidx.compose.runtime.getValue
4546
import androidx.compose.runtime.mutableStateOf
4647
import androidx.compose.runtime.remember
4748
import androidx.compose.runtime.setValue
49+
import androidx.compose.ui.Alignment
4850
import androidx.compose.ui.Modifier
4951
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
5052
import androidx.compose.ui.platform.LocalContext
5153
import androidx.compose.ui.platform.LocalHapticFeedback
5254
import androidx.compose.ui.res.painterResource
5355
import androidx.compose.ui.unit.dp
5456
import androidx.compose.ui.unit.sp
57+
import androidx.compose.ui.zIndex
5558
import androidx.navigation.NavDestination.Companion.hasRoute
5659
import androidx.navigation.NavDestination.Companion.hierarchy
5760
import androidx.navigation.NavGraph.Companion.findStartDestination
@@ -82,6 +85,8 @@ import org.aquamarine5.brainspark.chaoxingsignfaker.screen.CourseDetailDestinati
8285
import org.aquamarine5.brainspark.chaoxingsignfaker.screen.CourseDetailScreen
8386
import org.aquamarine5.brainspark.chaoxingsignfaker.screen.CourseListDestination
8487
import org.aquamarine5.brainspark.chaoxingsignfaker.screen.CourseListScreen
88+
import org.aquamarine5.brainspark.chaoxingsignfaker.screen.GestureSignDestination
89+
import org.aquamarine5.brainspark.chaoxingsignfaker.screen.GestureSignScreen
8590
import org.aquamarine5.brainspark.chaoxingsignfaker.screen.GetLocationDestination
8691
import org.aquamarine5.brainspark.chaoxingsignfaker.screen.LocationSignScreen
8792
import org.aquamarine5.brainspark.chaoxingsignfaker.screen.LoginDestination
@@ -102,6 +107,7 @@ import org.aquamarine5.brainspark.chaoxingsignfaker.screen.SignGraphDestination
102107
import org.aquamarine5.brainspark.chaoxingsignfaker.screen.WelcomeDestination
103108
import org.aquamarine5.brainspark.chaoxingsignfaker.screen.WelcomeScreen
104109
import org.aquamarine5.brainspark.chaoxingsignfaker.ui.theme.ChaoxingSignFakerTheme
110+
import org.aquamarine5.brainspark.chaoxingsignfaker.ui.theme.Orange
105111
import org.aquamarine5.brainspark.stackbricks.StackbricksPolicy
106112
import org.aquamarine5.brainspark.stackbricks.StackbricksService
107113
import org.aquamarine5.brainspark.stackbricks.providers.qiniu.QiniuConfiguration
@@ -241,9 +247,22 @@ class MainActivity : ComponentActivity() {
241247
CompositionLocalProvider(LocalContentColor provides iconColor) {
242248
Column {
243249
Spacer(modifier = Modifier.size(1.5.dp))
244-
BadgedBox(badge={
250+
BadgedBox(badge = {
245251
if (item.name == "设置" && isNewVersionAvailable) {
246-
Badge()
252+
Box(contentAlignment = Alignment.Center) {
253+
Badge(
254+
containerColor = MaterialTheme.colorScheme.primaryContainer,
255+
modifier = Modifier
256+
.size(16.dp)
257+
.zIndex(0f)
258+
)
259+
Badge(
260+
containerColor = Orange,
261+
modifier = Modifier
262+
.size(10.dp)
263+
.zIndex(10f)
264+
)
265+
}
247266
}
248267
}) {
249268
Icon(
@@ -428,6 +447,18 @@ class MainActivity : ComponentActivity() {
428447
}
429448
}
430449

450+
composable<GestureSignDestination> { route ->
451+
GestureSignScreen(
452+
route.toRoute(), navToOtherSign = {
453+
navController.navigate(it)
454+
},
455+
navToCourseDetailDestination = {
456+
navController.navigateUp()
457+
}) {
458+
navController.navigate(OtherUserGraphDestination)
459+
}
460+
}
461+
431462
composable<PasswordSignDestination> { route ->
432463
PasswordSignScreen(
433464
route.toRoute(), navToOtherSign = {

app/src/main/java/org/aquamarine5/brainspark/chaoxingsignfaker/UMengHelper.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ object UMengHelper {
2525
private const val EVENT_TAG_SIGN_LOCATION = "sign_location"
2626
private const val EVENT_TAG_SIGN_PASSWORD = "sign_password"
2727
private const val EVENT_TAG_SIGN_QR_CODE = "sign_qr_code"
28+
private const val EVENT_TAG_SIGN_GESTURE = "sign_gesture"
2829
private const val EVENT_TAG_SIGN_PHOTO = "sign_photo"
2930
private const val EVENT_TAG_SIGN_CLICK = "sign_click"
3031
private const val EVENT_TAG_ADD_OTHER_USER = "account_add_other_user"
@@ -87,6 +88,19 @@ object UMengHelper {
8788
)
8889
}
8990

91+
suspend fun onSignGestureEvent(
92+
context: Context,
93+
name: String, isOtherUser: Boolean = false
94+
) {
95+
onEvent(
96+
context, EVENT_TAG_SIGN_GESTURE, mapOf(
97+
"user" to name
98+
)
99+
)
100+
ChaoxingAnalyser.onGestureSignEvent(context)
101+
if (isOtherUser) ChaoxingAnalyser.onOtherUserSignEvent(context)
102+
}
103+
90104
suspend fun onSignCodeEvent(
91105
context: Context,
92106
name: String, isOtherUser: Boolean = false

app/src/main/java/org/aquamarine5/brainspark/chaoxingsignfaker/api/ChaoxingRecommendHelper.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,10 @@ object ChaoxingRecommendHelper {
142142
client: ChaoxingHttpClient
143143
) =
144144
withContext(Dispatchers.IO) {
145+
return@withContext
145146
val time = LocalDateTime.now()
146147
context.chaoxingDataStore.updateData { datastore ->
147-
if(1==1||datastore.disableRecommend) return@updateData datastore // TODO(Fix it later)
148+
if (datastore.disableRecommend) return@updateData datastore
148149
datastore.toBuilder().apply {
149150
val newRecord = RecommendRecord.newBuilder()
150151
.setDayOfWeek(time.dayOfWeek.value)

app/src/main/java/org/aquamarine5/brainspark/chaoxingsignfaker/api/ChaoxingSignHelper.kt

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,34 @@ import org.aquamarine5.brainspark.chaoxingsignfaker.ChaoxingPredictableException
2020
import org.aquamarine5.brainspark.chaoxingsignfaker.R
2121
import org.aquamarine5.brainspark.chaoxingsignfaker.checkResponse
2222
import org.aquamarine5.brainspark.chaoxingsignfaker.entity.ChaoxingSignActivityEntity
23+
import org.aquamarine5.brainspark.chaoxingsignfaker.screen.GestureSignDestination
2324
import org.aquamarine5.brainspark.chaoxingsignfaker.screen.GetLocationDestination
2425
import org.aquamarine5.brainspark.chaoxingsignfaker.screen.PasswordSignDestination
2526
import org.aquamarine5.brainspark.chaoxingsignfaker.screen.PhotoSignDestination
2627
import org.aquamarine5.brainspark.chaoxingsignfaker.screen.QRCodeSignDestination
2728
import org.aquamarine5.brainspark.chaoxingsignfaker.signer.ChaoxingSigner
29+
import java.util.concurrent.ConcurrentHashMap
2830

2931
object ChaoxingSignHelper {
3032
const val TIMEOUT_SHOW_SPONSOR_AFTER_ALL_SIGNED = 250L
33+
private val signIconMap = mapOf(
34+
"0" to R.drawable.ic_square_mouse_pointer,
35+
"3" to R.drawable.ic_pattern_locking,
36+
"4" to R.drawable.ic_map_pin,
37+
"2" to R.drawable.ic_scan_qr_code,
38+
"5" to R.drawable.ic_binary
39+
)
40+
41+
private val painterCache = ConcurrentHashMap<Int, Painter>(6)
3142

3243
class ChaoxingUnsupportedSignTypeException : ChaoxingPredictableException("不支持此签到类型")
3344

3445
@Composable
35-
fun getSignIcon(activity: ChaoxingSignActivityEntity): Painter = when (activity.otherId) {
36-
"0" -> painterResource(R.drawable.ic_square_mouse_pointer)
37-
"3" -> painterResource(R.drawable.ic_git_branch)
38-
"4" -> painterResource(R.drawable.ic_map_pin)
39-
"2" -> painterResource(R.drawable.ic_scan_qr_code)
40-
"5" -> painterResource(R.drawable.ic_binary)
41-
else -> painterResource(R.drawable.ic_clipboard_pen_line)
46+
fun getSignIcon(activity: ChaoxingSignActivityEntity): Painter {
47+
val iconRes = signIconMap[activity.otherId] ?: R.drawable.ic_clipboard_pen_line
48+
return painterCache.getOrPut(iconRes) {
49+
painterResource(id = iconRes)
50+
}
4251
}
4352

4453
fun getSignDestination(
@@ -51,6 +60,7 @@ object ChaoxingSignHelper {
5160
"4" -> GetLocationDestination.parseFromSignActivityEntity(activityEntity, isLate)
5261
"2" -> QRCodeSignDestination.parseFromSignActivityEntity(activityEntity, isLate)
5362
"0" -> PhotoSignDestination.parseFromSignActivityEntity(activityEntity, isLate)
63+
"3" -> GestureSignDestination.parseFromSignActivityEntity(activityEntity, isLate)
5464
else -> {
5565
Toast.makeText(context, "暂不支持该活动类型", Toast.LENGTH_SHORT).show()
5666
null
@@ -117,6 +127,16 @@ object ChaoxingSignHelper {
117127
if (endTime != null) System.currentTimeMillis() > endTime else false
118128
)
119129

130+
3-> GestureSignDestination(
131+
activeId,
132+
classId,
133+
courseId,
134+
"",
135+
result.getLong("starttime"),
136+
endTime,
137+
if (endTime != null) System.currentTimeMillis() > endTime else false
138+
)
139+
120140
else -> {
121141
throw ChaoxingUnsupportedSignTypeException()
122142
}

app/src/main/java/org/aquamarine5/brainspark/chaoxingsignfaker/components/CaptchaHandlerDialog.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,11 @@ fun CaptchaHandlerDialog(
6464
var sliderPosition by remember(data) { mutableFloatStateOf(0f) }
6565
var containerWidth by remember { mutableFloatStateOf(320f) }
6666
val snackbar = LocalSnackbarHostState.current
67-
val context= LocalContext.current
67+
val context = LocalContext.current
6868
val hapticFeedback = LocalHapticFeedback.current
6969
val coroutineScope = rememberCoroutineScope()
7070
val density by remember(containerWidth) { mutableFloatStateOf(containerWidth / 320) }
71-
val sliderMaxValue = remember(containerWidth) { containerWidth-56f * density }
71+
val sliderMaxValue = remember(containerWidth) { containerWidth - 56f * density }
7272
LaunchedEffect(signer) {
7373
data = signer.getCaptchaImageV2()
7474
}
@@ -119,7 +119,7 @@ fun CaptchaHandlerDialog(
119119
// (-8 ~ 272) + 28
120120
// 0 ~280
121121
val normalizedPosition =
122-
(sliderPosition / sliderMaxValue) * 280f-8
122+
(sliderPosition / sliderMaxValue) * 280f - 8
123123

124124
signer.checkCaptchaResult(normalizedPosition, data!!)
125125
.let { result ->
@@ -128,7 +128,11 @@ fun CaptchaHandlerDialog(
128128
HapticFeedbackType.Reject
129129
)
130130
sliderPosition = 0f
131-
Toast.makeText(context,"验证失败,请重试",Toast.LENGTH_SHORT).show()
131+
Toast.makeText(
132+
context,
133+
"验证失败,请重试",
134+
Toast.LENGTH_SHORT
135+
).show()
132136
data = signer.getCaptchaImageV2()
133137
} else {
134138
onResult(Result.success(result))

app/src/main/java/org/aquamarine5/brainspark/chaoxingsignfaker/components/CourseSignActivityColumnCard.kt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,17 +75,20 @@ inline fun CourseSignActivityColumnCard(
7575
val currentTime = remember { System.currentTimeMillis() }
7676
BadgedBox(badge = {
7777
if (currentTime - activity.startTime <= 600000) {
78-
Box(contentAlignment = Alignment.Center){
78+
Box(contentAlignment = Alignment.Center) {
7979
Badge(
8080
containerColor = MaterialTheme.colorScheme.background,
81-
modifier = Modifier.size(16.dp).zIndex(0f)
81+
modifier = Modifier
82+
.size(16.dp)
83+
.zIndex(0f)
8284
)
8385
Badge(
8486
containerColor = Orange,
85-
modifier = Modifier.size(10.dp).zIndex(10f)
87+
modifier = Modifier
88+
.size(10.dp)
89+
.zIndex(10f)
8690
)
8791
}
88-
8992
}
9093
}) {
9194
Icon(

0 commit comments

Comments
 (0)