Compare commits
No commits in common. "5bf8a85f7a3c427e197b114805edf6d711338d51" and "8f24706d8c9588bd044af63ee9cce4b940023938" have entirely different histories.
5bf8a85f7a
...
8f24706d8c
1
.gitignore
vendored
@ -23,4 +23,3 @@ node_modules/
|
||||
logs/
|
||||
.claude/
|
||||
docs/superpowers/
|
||||
.worktrees/
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
|
||||
纯 Android + Jetpack Compose 日历应用。功能:农历/节气/节日、个人班次排期(WORK/OFF 循环)、月/周/年三视图。
|
||||
|
||||
> **README 与实际不符**:README 提及 "Kotlin Multiplatform / iOS",实际为纯 Android 项目。模块名为 `:core` 和 `:app`,无 `:shared` 或 `:androidApp`。
|
||||
|
||||
## 模块结构
|
||||
|
||||
| 模块 | 类型 | 职责 |
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
纯 Android + Jetpack Compose 日历应用,支持农历/节气/节日、个人班次排期,提供月/周/年三种视图。
|
||||
|
||||
<div>
|
||||
<img src="core/src/main/assets/app_icon.webp" width="128" height="128" />
|
||||
<img src="app/src/main/assets/app_icon.png" />
|
||||
</div>
|
||||
|
||||
## 特性
|
||||
@ -19,8 +19,8 @@
|
||||
- Kotlin 2.3 · Jetpack Compose · Material 3
|
||||
- `kotlinx-datetime` 处理所有日期逻辑
|
||||
- `tyme4kt` 提供农历、节气与传统节日
|
||||
- `sketch` 渲染动画 WebP
|
||||
- 三模块:`:core`(UI + 逻辑) · `:app`(薄壳) · `:macrobenchmark`(Baseline Profile 生成)
|
||||
- `sketch` 渲染 GIF 动画
|
||||
- 双模块:`:core`(UI + 逻辑) · `:app`(薄壳)
|
||||
|
||||
## 构建
|
||||
|
||||
|
||||
@ -1,25 +1,25 @@
|
||||
<!-- Parent: ../AGENTS.md -->
|
||||
<!-- Generated: 2026-05-22 | Updated: 2026-06-15 -->
|
||||
<!-- Generated: 2026-05-22 | Updated: 2026-05-22 -->
|
||||
|
||||
# assets
|
||||
|
||||
## Purpose
|
||||
`:app` 模块原始资产文件目录。当前为空(2026-06 清理后)。
|
||||
原始资产文件目录,存放不需要 Android 资源系统处理的二进制文件。当前包含 GIF 动画资源。
|
||||
|
||||
## Key Files
|
||||
|
||||
无
|
||||
无顶层文件
|
||||
|
||||
## Subdirectories
|
||||
|
||||
无(原 `gifs/` 子目录的镜像说明已删除 —— 实际 UI/WebP 资源只在 `:core`)
|
||||
| Directory | Purpose |
|
||||
|-----------|---------|
|
||||
| `gifs/` | GIF 动画资源(见 `gifs/AGENTS.md`) |
|
||||
|
||||
## For AI Agents
|
||||
|
||||
### Working In This Directory
|
||||
- 历史上此目录曾放 `app_icon.png`/`app_icon_original.png` 作图标源,因无代码引用已于 2026-06 删除
|
||||
- 应用内图标用 `core/src/main/assets/app_icon.webp`(`Platform.kt`)
|
||||
- 启动器图标用 `app/src/main/res/mipmap-*/`(含 Adaptive Icon)
|
||||
- **不要再把图标源 PNG 放这里**:会被打进 APK。原图 `app_icon_original.png` (2048px) 保留在 git 历史(commit `a36f6c4`),重新生成 foreground 时用 `git show a36f6c4:app/src/main/assets/app_icon_original.png` 恢复,生成脚本见 `docs/superpowers/plans/2026-06-15-image-management-optimization.md` Task 5
|
||||
- 新增原始资源文件直接放入此目录或其子目录
|
||||
- 通过 `AssetManager` 在运行时访问
|
||||
|
||||
<!-- MANUAL: -->
|
||||
|
||||
BIN
app/src/main/assets/app_icon.png
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
app/src/main/assets/app_icon_original.png
Normal file
|
After Width: | Height: | Size: 457 KiB |
33
app/src/main/assets/gifs/AGENTS.md
Normal file
@ -0,0 +1,33 @@
|
||||
<!-- Parent: ../AGENTS.md -->
|
||||
<!-- Generated: 2026-05-22 | Updated: 2026-05-22 -->
|
||||
|
||||
# gifs
|
||||
|
||||
## Purpose
|
||||
GIF 动画资源目录,存放应用使用的动画 GIF 文件(001.gif ~ 152.gif),由 `AnimatedGif` Composable 组件通过 `sketch` 库加载显示。
|
||||
|
||||
## Key Files
|
||||
|
||||
| File | Description |
|
||||
|------|-------------|
|
||||
| `001.gif` ~ `152.gif` | 应用动画 GIF 资源 |
|
||||
|
||||
## Subdirectories
|
||||
无
|
||||
|
||||
## For AI Agents
|
||||
|
||||
### Working In This Directory
|
||||
- 替换或新增 GIF 时保持连续编号
|
||||
- GIF 文件较大,注意 APK 体积影响
|
||||
- `AnimatedGif` 组件使用 `sketch` 库异步加载和播放
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Internal
|
||||
- `core/src/main/kotlin/plus/rua/project/ui/AnimatedGif.kt` — GIF 显示组件
|
||||
|
||||
### External
|
||||
- `sketch` 4.4.0(GIF 解码和播放)
|
||||
|
||||
<!-- MANUAL: -->
|
||||
@ -13,13 +13,13 @@ class MainActivity : BaseActivity() {
|
||||
setContent {
|
||||
YaYaTheme {
|
||||
CalendarMonthView(
|
||||
onNavigateToAbout = {
|
||||
startActivityWithSlide(Intent(this, AboutActivity::class.java))
|
||||
},
|
||||
onNavigateToTools = {
|
||||
startActivityWithSlide(Intent(this, ToolsActivity::class.java))
|
||||
}
|
||||
)
|
||||
onNavigateToAbout = {
|
||||
startActivityWithSlide(Intent(this, AboutActivity::class.java))
|
||||
},
|
||||
onNavigateToTools = {
|
||||
startActivityWithSlide(Intent(this, ToolsActivity::class.java))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Adaptive Icon 背景: 纯色块, 取自原图四角采样 RGB(131,208,241) -->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#83D0F1"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
</vector>
|
||||
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Adaptive Icon (API 26+): 系统按 OEM 启动器形状自动裁切背景+前景。
|
||||
-->
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Adaptive Icon 圆形版 (API 26+), 内容与 ic_launcher.xml 一致 -->
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
|
Before Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 10 KiB |
@ -12,21 +12,6 @@ android {
|
||||
defaultConfig {
|
||||
minSdk = libs.versions.android.minSdk.get().toInt()
|
||||
consumerProguardFiles("proguard-rules.pro")
|
||||
|
||||
// 构建期扫描 assets/animations/ 生成 WebP 文件列表,避免运行期硬编码 (1..152)
|
||||
// 与 assets/ 目录耦合却不校验,导致增删文件后隐性 bug
|
||||
val webpFiles = layout.projectDirectory
|
||||
.dir("src/main/assets/animations")
|
||||
.asFile
|
||||
.listFiles { f -> f.extension.equals("webp", ignoreCase = true) }
|
||||
?.map { it.name }
|
||||
?.sorted()
|
||||
?: emptyList()
|
||||
require(webpFiles.isNotEmpty()) { "assets/animations/ 不应为空,请检查目录" }
|
||||
// 拼成 Java 数组字面量: new String[]{"001.webp","002.webp",...}
|
||||
val quoted = webpFiles.joinToString(",") { name -> "\"$name\"" }
|
||||
val arrayLiteral = "new String[]{$quoted}"
|
||||
buildConfigField("String[]", "WEBP_FILES", arrayLiteral)
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
@ -35,6 +20,7 @@ android {
|
||||
}
|
||||
release {
|
||||
isMinifyEnabled = false
|
||||
consumerProguardFiles("proguard-rules.pro")
|
||||
buildConfigField("boolean", "ENABLE_TRACE", "false")
|
||||
}
|
||||
create("trace") {
|
||||
|
||||
28
core/proguard-rules.pro
vendored
@ -1,6 +1,34 @@
|
||||
# Baseline Profiles 保留规则:确保方法名不被 R8 混淆,使 profile 规则匹配正确
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# ========== 启动热点路径保留 ==========
|
||||
|
||||
# DayCell — 启动最热点
|
||||
-keepclassmembers class plus.rua.project.ui.DayCellKt {
|
||||
public static void DayCell(...);
|
||||
}
|
||||
|
||||
# LunarCache — 日期计算缓存
|
||||
-keepclassmembers class plus.rua.project.LunarCache {
|
||||
public static plus.rua.project.DayCellInfo getOrCompute(kotlinx.datetime.LocalDate);
|
||||
public static java.lang.String formatLunarDate(kotlinx.datetime.LocalDate);
|
||||
public static void precompute(...);
|
||||
}
|
||||
|
||||
# DayCellInfo 数据类
|
||||
-keepclassmembers class plus.rua.project.DayCellInfo {
|
||||
public java.lang.String getAnnotationText();
|
||||
public boolean getIsAnnotationHighlight();
|
||||
public java.lang.String getHolidayBadge();
|
||||
public java.lang.String getLunarMonthName();
|
||||
}
|
||||
|
||||
# CalendarMonthPage
|
||||
-keepclassmembers class plus.rua.project.ui.CalendarMonthPageKt {
|
||||
public static void CalendarMonthPage(...);
|
||||
public static java.util.List generateMonthDays(...);
|
||||
}
|
||||
|
||||
# ========== 第三方库保留 ==========
|
||||
-keep class kotlinx.datetime.** { *; }
|
||||
-keep class cn.tyme.** { *; }
|
||||
|
||||
@ -1,28 +1,25 @@
|
||||
<!-- Parent: ../AGENTS.md -->
|
||||
<!-- Generated: 2026-05-22 | Updated: 2026-06-15 -->
|
||||
<!-- Generated: 2026-05-22 | Updated: 2026-05-22 -->
|
||||
|
||||
# assets
|
||||
|
||||
## Purpose
|
||||
核心模块原始资产文件目录,通过 `AssetManager` 在运行时访问。包含应用内图标和动画 WebP 资源。
|
||||
核心模块原始资产文件目录,与 `app/src/main/assets/` 镜像,包含 GIF 动画资源供 `AnimatedGif` Composable 组件加载。
|
||||
|
||||
## Key Files
|
||||
|
||||
| File | Description |
|
||||
|------|-------------|
|
||||
| `app_icon.webp` | 应用内展示用的图标(`Platform.kt` 的 `getAppIconUri()` 引用) |
|
||||
无顶层文件
|
||||
|
||||
## Subdirectories
|
||||
|
||||
| Directory | Purpose |
|
||||
|-----------|---------|
|
||||
| `animations/` | 动画 WebP 资源(见 `animations/AGENTS.md`) |
|
||||
| `gifs/` | GIF 动画资源(见 `gifs/AGENTS.md`) |
|
||||
|
||||
## For AI Agents
|
||||
|
||||
### Working In This Directory
|
||||
- 新增原始资源文件直接放入此目录或其子目录
|
||||
- **不与 `app/src/main/assets/` 镜像**:启动器图标在 `:app`,UI/WebP 资源在 `:core`
|
||||
- 通过 `file:///android_asset/<path>` URI 在运行时访问
|
||||
- 此目录与 `app/src/main/assets/` 内容同步
|
||||
- 通过 `AssetManager` 在运行时访问
|
||||
|
||||
<!-- MANUAL: -->
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
<!-- Parent: ../AGENTS.md -->
|
||||
<!-- Generated: 2026-05-22 | Updated: 2026-06-15 -->
|
||||
|
||||
# animations
|
||||
|
||||
## Purpose
|
||||
动画 WebP 资源目录,存放应用日历切换时随机展示的动画(文件名 `001.webp` ~ `NNN.webp`,由构建期扫描生成)。由 `AnimatedWebp` Composable 通过 `sketch` 库加载。
|
||||
|
||||
> 历史命名曾为 `gifs/`(2026-06 前),实际格式一直是 WebP 动画,现已正名。
|
||||
|
||||
## Key Files
|
||||
|
||||
| File | Description |
|
||||
|------|-------------|
|
||||
| `001.webp` ~ `NNN.webp` | 动画 WebP 资源,编号零填充三位 |
|
||||
|
||||
## Subdirectories
|
||||
无
|
||||
|
||||
## For AI Agents
|
||||
|
||||
### Working In This Directory
|
||||
- 替换或新增 WebP 时保持连续三位编号(如 `153.webp`)
|
||||
- **无需手动更新列表**:`core/build.gradle.kts` 在构建期扫描本目录生成 `BuildConfig.WEBP_FILES`
|
||||
- 由 `AnimatedWebpFilesTest` 守卫目录与列表一致
|
||||
- WebP 文件较大,注意 APK 体积
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Internal
|
||||
- `core/src/main/kotlin/plus/rua/project/ui/AnimatedWebp.kt` — WebP 显示组件
|
||||
- `core/build.gradle.kts` — 构建期扫描注入 `BuildConfig.WEBP_FILES`
|
||||
|
||||
### External
|
||||
- `sketch` 4.4.0(`sketch-animated-webp`,动画 WebP 解码播放)
|
||||
|
||||
<!-- MANUAL: -->
|
||||
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 9.8 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
|
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.0 KiB |
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |