Skip to content

Commit 4216f37

Browse files
committed
fix buttons and android build
1 parent 6f24d31 commit 4216f37

6 files changed

Lines changed: 117 additions & 15 deletions

File tree

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Goal Details: Best & Worst Games
2+
3+
## Description
4+
5+
On the goal details page, show two sections: **Best Games** and **Worst Games** ranked by performance according to that goal's metric.
6+
7+
## Requirements
8+
9+
### Game Lists
10+
- Show the top N best and worst matches scored by the goal's metric (e.g. lowest deaths for a deaths goal, highest win rate context, etc.)
11+
- Each match row should be clickable and open the **match details page** (same as used elsewhere in the app)
12+
13+
### Filters
14+
15+
#### Hero Filter
16+
- If the goal is **not** hero-specific (i.e. applies to "any hero"), show a **hero filter** so the user can narrow results to a specific hero
17+
18+
#### Game Mode Filter
19+
- If the goal's hero filter is set to **"any"**, show a **ranked/turbo filter** (All / Ranked / Turbo) to let the user slice results by game mode
20+
21+
### Sorting / Scoring
22+
- Best games = matches where the goal metric was most achieved (e.g. fewest deaths, highest KDA, etc.)
23+
- Worst games = matches where the goal metric was least achieved
24+
- Use the same metric logic already used to evaluate goal pass/fail
25+
26+
## Acceptance Criteria
27+
- [ ] Best games section visible on goal details page
28+
- [ ] Worst games section visible on goal details page
29+
- [ ] Hero filter shown when goal applies to any hero
30+
- [ ] Game mode filter (All / Ranked / Turbo) shown when goal hero is "any"
31+
- [ ] Clicking a match opens the match details page
32+
- [ ] Filters update both best and worst lists reactively
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Match Details: Compare to Another Match
2+
3+
**Epic: Performance Journal**
4+
5+
## Description
6+
7+
On the match details page, allow the user to compare the current match side-by-side with another match. A "Compare to" button opens a selection popup with quick options and a manual entry field.
8+
9+
## Requirements
10+
11+
### "Compare to" Button (Match Details Page)
12+
- Add a **Compare to** button on the match details page
13+
- Opens a popup with the following options:
14+
- **Last game** — compare to the most recent match in history
15+
- **Last game with this hero** — compare to the most recent match played on the same hero
16+
- **Specific match ID** — text input to enter an arbitrary match ID manually
17+
18+
### Comparison View
19+
- Once a comparison target is selected, show both matches side-by-side (or stacked on smaller layouts)
20+
- Highlight differences in key stats (KDA, GPM, XPM, deaths, hero damage, etc.)
21+
- Make it clear which match is "this match" vs "comparison match"
22+
23+
### Compare Buttons in Matches List (per Goal)
24+
- In the matches list popup/modal (used on goal details or elsewhere), add a **Compare to best** button for each match row
25+
- "Best" = the best match for that goal according to the goal's metric
26+
- Clicking it navigates to / opens the match details page in comparison mode with that goal's best match pre-selected
27+
28+
## Acceptance Criteria
29+
- [ ] "Compare to" button visible on match details page
30+
- [ ] Popup shows: Last game, Last game with this hero, Specific match ID input
31+
- [ ] Selecting any option loads the comparison view
32+
- [ ] Comparison view clearly labels both matches and highlights stat differences
33+
- [ ] Matches list popup has a "Compare to best" button per match for each goal context
34+
- [ ] "Compare to best" opens match details in comparison mode with the goal's best match

scripts/reset-android-emulator.ps1

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# reset-android-emulator.ps1
2+
# Kills running emulator processes and deletes all AVDs so they can be recreated fresh.
3+
4+
$avdmanager = "$env:LOCALAPPDATA\Android\Sdk\cmdline-tools\latest\bin\avdmanager.bat"
5+
$emulatorBin = "$env:LOCALAPPDATA\Android\Sdk\emulator\emulator.exe"
6+
$adb = "$env:LOCALAPPDATA\Android\Sdk\platform-tools\adb.exe"
7+
8+
# 1. Kill running emulators
9+
Write-Host "Stopping running emulators..." -ForegroundColor Cyan
10+
& $adb kill-server 2>$null
11+
Get-Process -Name "emulator*", "qemu-system*" -ErrorAction SilentlyContinue | ForEach-Object {
12+
Write-Host " Killing $($_.Name) (pid $($_.Id))"
13+
Stop-Process -Id $_.Id -Force
14+
}
15+
Start-Sleep -Seconds 2
16+
17+
# 2. List AVDs
18+
Write-Host "`nExisting AVDs:" -ForegroundColor Cyan
19+
$avds = & $avdmanager list avd -c 2>$null
20+
if (-not $avds) {
21+
Write-Host " (none found)"
22+
} else {
23+
$avds | ForEach-Object { Write-Host " $_" }
24+
}
25+
26+
# 3. Delete each AVD
27+
$avds | Where-Object { $_ -match '\S' } | ForEach-Object {
28+
$name = $_.Trim()
29+
Write-Host "`nDeleting AVD: $name" -ForegroundColor Yellow
30+
& $avdmanager delete avd -n $name
31+
}
32+
33+
Write-Host "`nDone. Run 'cargo tauri android dev' to create a fresh emulator." -ForegroundColor Green

src-tauri/gen/android/app/build.gradle.kts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,12 @@ android {
1818
namespace = "com.volthawk.dota_keeper"
1919
defaultConfig {
2020
manifestPlaceholders["usesCleartextTraffic"] = "false"
21+
applicationId = "com.volthawk.dota_keeper"
2122
minSdk = 24
2223
targetSdk = 36
2324
versionCode = tauriProperties.getProperty("tauri.android.versionCode", "1").toInt()
2425
versionName = tauriProperties.getProperty("tauri.android.versionName", "1.0")
2526
}
26-
flavorDimensions += "channel"
27-
productFlavors {
28-
create("production") {
29-
applicationId = "com.dotakeeper.dotakeeper"
30-
}
31-
create("beta") {
32-
applicationId = "com.dotakeeper.dotakeeper_beta"
33-
}
34-
}
3527
buildTypes {
3628
getByName("debug") {
3729
manifestPlaceholders["usesCleartextTraffic"] = "true"

src-tauri/gen/android/app/src/main/java/com/volthawk/dota_keeper/MainActivity.kt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,12 @@ class MainActivity : TauriActivity() {
3636

3737
override fun onResume() {
3838
super.onResume()
39-
// Re-inject after a short delay to ensure the page has finished loading
40-
// (covers initial launch where onResume fires before the SvelteKit app loads).
39+
// Re-inject at multiple delays to ensure at least one attempt lands after
40+
// the SvelteKit app has fully loaded. 300 ms catches fast resumes;
41+
// 1 s and 3 s cover cold-start where the Tauri/Wry bundle takes longer.
4142
handler.postDelayed({ injectInsets() }, 300)
43+
handler.postDelayed({ injectInsets() }, 1000)
44+
handler.postDelayed({ injectInsets() }, 3000)
4245
}
4346

4447
private fun injectInsets() {
@@ -55,5 +58,10 @@ class MainActivity : TauriActivity() {
5558
override fun onWebViewCreate(webView: WebView) {
5659
webViewRef = webView
5760
webView.setBackgroundColor(Color.parseColor("#111827"))
61+
// Inject insets once the WebView exists — retried at increasing delays so
62+
// at least one attempt lands after the SvelteKit bundle has executed.
63+
handler.postDelayed({ injectInsets() }, 300)
64+
handler.postDelayed({ injectInsets() }, 1000)
65+
handler.postDelayed({ injectInsets() }, 3000)
5866
}
5967
}

src-tauri/gen/android/buildSrc/src/main/java/com/volthawk/dota_keeper/kotlin/RustPlugin.kt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,11 @@ open class RustPlugin : Plugin<Project> {
5757
description = "Build dynamic library in $profile mode for all targets"
5858
}
5959

60-
tasks["mergeUniversal${profileCapitalized}JniLibFolders"].dependsOn(buildTask)
60+
// Use matching() so extra flavor dimensions (e.g. "channel") in the
61+
// variant name don't break the lookup (task is e.g.
62+
// mergeUniversalBetaDebugJniLibFolders, not mergeUniversalDebugJniLibFolders).
63+
tasks.matching { it.name.matches(Regex("mergeUniversal.*${profileCapitalized}JniLibFolders")) }
64+
.configureEach { dependsOn(buildTask) }
6165

6266
for (targetPair in targetsList.withIndex()) {
6367
val targetName = targetPair.value
@@ -75,9 +79,8 @@ open class RustPlugin : Plugin<Project> {
7579
}
7680

7781
buildTask.dependsOn(targetBuildTask)
78-
tasks["merge$targetArchCapitalized${profileCapitalized}JniLibFolders"].dependsOn(
79-
targetBuildTask
80-
)
82+
tasks.matching { it.name.matches(Regex("merge${targetArchCapitalized}.*${profileCapitalized}JniLibFolders")) }
83+
.configureEach { dependsOn(targetBuildTask) }
8184
}
8285
}
8386
}

0 commit comments

Comments
 (0)