Compare commits

..

No commits in common. "5bf8a85f7a3c427e197b114805edf6d711338d51" and "8f24706d8c9588bd044af63ee9cce4b940023938" have entirely different histories.

192 changed files with 429 additions and 1011 deletions

1
.gitignore vendored
View File

@ -23,4 +23,3 @@ node_modules/
logs/
.claude/
docs/superpowers/
.worktrees/

View File

@ -2,6 +2,8 @@
纯 Android + Jetpack Compose 日历应用。功能:农历/节气/节日、个人班次排期WORK/OFF 循环)、月/周/年三视图。
> **README 与实际不符**README 提及 "Kotlin Multiplatform / iOS",实际为纯 Android 项目。模块名为 `:core``:app`,无 `:shared``:androidApp`
## 模块结构
| 模块 | 类型 | 职责 |

View File

@ -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`(薄壳)
## 构建

View File

@ -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: -->

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 KiB

View 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.0GIF 解码和播放)
<!-- MANUAL: -->

View File

@ -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))
}
)
}
}
}

View File

@ -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>

View File

@ -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>

View File

@ -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>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

View File

@ -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") {

View File

@ -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.** { *; }

View File

@ -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: -->

View File

@ -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: -->

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 75 KiB

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 69 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

View File

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 63 KiB

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Some files were not shown because too many files have changed in this diff Show More