Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7f450aab17 | |||
| d8f67dcad3 | |||
| ccb77f76b8 | |||
| da54faf8e2 | |||
| f3d01b5890 |
@@ -92,7 +92,18 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload APK to release
|
- name: Upload APK to release
|
||||||
run: |
|
run: |
|
||||||
|
BASE="${{ env.GITEA_URL }}/api/v1/repos/${{ env.REPO }}"
|
||||||
|
AUTH="Authorization: token ${{ secrets.CI_TOKEN }}"
|
||||||
|
RELEASE_ID="${{ steps.release.outputs.id }}"
|
||||||
|
|
||||||
|
# Remove any existing APK assets so re-runs don't accumulate duplicates.
|
||||||
|
curl -sf -H "$AUTH" "$BASE/releases/$RELEASE_ID/assets" \
|
||||||
|
| python3 -c "import sys,json; [print(a['id']) for a in json.load(sys.stdin) if a['name'].endswith('.apk')]" \
|
||||||
|
| while read AID; do
|
||||||
|
curl -sf -X DELETE -H "$AUTH" "$BASE/releases/$RELEASE_ID/assets/$AID"
|
||||||
|
done
|
||||||
|
|
||||||
curl -sf -X POST \
|
curl -sf -X POST \
|
||||||
-H "Authorization: token ${{ secrets.CI_TOKEN }}" \
|
-H "$AUTH" \
|
||||||
-F "attachment=@${{ env.APK_OUT }};type=application/vnd.android.package-archive" \
|
-F "attachment=@${{ env.APK_OUT }};type=application/vnd.android.package-archive" \
|
||||||
"${{ env.GITEA_URL }}/api/v1/repos/${{ env.REPO }}/releases/${{ steps.release.outputs.id }}/assets"
|
"$BASE/releases/$RELEASE_ID/assets"
|
||||||
|
|||||||
@@ -6,6 +6,28 @@ project follows [Semantic Versioning](https://semver.org/).
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [0.31.0] — 2026-05-16
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **Face-down cards rendered as solid red squares on AMOLED phones** (Bug 1).
|
||||||
|
The dark theme's card back (`back.svg`) uses a near-black background
|
||||||
|
(`#151515`) which AMOLED screens render as fully-off pixels, leaving only a
|
||||||
|
tiny `#a54242` red badge visible — exactly what was reported. Fixed by
|
||||||
|
changing the fresh-install default theme from "dark" to "classic" (white
|
||||||
|
background with navy diamond pattern, clearly readable on all display types).
|
||||||
|
Also corrected stale asset paths in `load_card_images` (`cards/backs/back_N`
|
||||||
|
→ `cards/backs/classic/back_N`, `cards/faces/XY` → `cards/faces/classic/XY`)
|
||||||
|
so the PNG fallback loads correctly when the embedded theme hasn't arrived yet.
|
||||||
|
|
||||||
|
## [0.30.0] — 2026-05-16
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- **Tableau card spacing tightened.** Face-up card fan reduced from 25% to 18%
|
||||||
|
of card height; face-down from 20% to 14%. Cards on tableau piles sit closer
|
||||||
|
together while still showing enough of each card to read the pile depth.
|
||||||
|
|
||||||
## [0.29.0] — 2026-05-16
|
## [0.29.0] — 2026-05-16
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
@@ -275,7 +275,7 @@ fn default_music_volume() -> f32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn default_theme_id() -> String {
|
fn default_theme_id() -> String {
|
||||||
"dark".to_string()
|
"classic".to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Default tooltip-hover dwell delay in seconds. Mirrors
|
/// Default tooltip-hover dwell delay in seconds. Mirrors
|
||||||
@@ -402,11 +402,10 @@ impl Settings {
|
|||||||
/// their respective ranges after deserialization or hand-editing of
|
/// their respective ranges after deserialization or hand-editing of
|
||||||
/// `settings.json`.
|
/// `settings.json`.
|
||||||
pub fn sanitized(self) -> Self {
|
pub fn sanitized(self) -> Self {
|
||||||
// Migrate stale theme IDs: "default" was removed when the theme was
|
// Migrate stale theme IDs: "default" was the original name before it
|
||||||
// renamed to "dark"; "classic" was briefly the default before "dark"
|
// was renamed to "dark".
|
||||||
// was restored as the shipped default.
|
|
||||||
let selected_theme_id = match self.selected_theme_id.as_str() {
|
let selected_theme_id = match self.selected_theme_id.as_str() {
|
||||||
"default" | "classic" => "dark".to_string(),
|
"default" => "dark".to_string(),
|
||||||
_ => self.selected_theme_id,
|
_ => self.selected_theme_id,
|
||||||
};
|
};
|
||||||
Self {
|
Self {
|
||||||
|
|||||||
@@ -484,13 +484,13 @@ fn load_card_images(asset_server: Option<Res<AssetServer>>, mut commands: Comman
|
|||||||
let faces: [[Handle<Image>; 13]; 4] = std::array::from_fn(|suit| {
|
let faces: [[Handle<Image>; 13]; 4] = std::array::from_fn(|suit| {
|
||||||
std::array::from_fn(|rank| {
|
std::array::from_fn(|rank| {
|
||||||
asset_server.load(format!(
|
asset_server.load(format!(
|
||||||
"cards/faces/{}{}.png",
|
"cards/faces/classic/{}{}.png",
|
||||||
RANK_STRS[rank], SUIT_CHARS[suit]
|
RANK_STRS[rank], SUIT_CHARS[suit]
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
let backs = std::array::from_fn(|i| {
|
let backs = std::array::from_fn(|i| {
|
||||||
asset_server.load(format!("cards/backs/back_{i}.png"))
|
asset_server.load(format!("cards/backs/classic/back_{i}.png"))
|
||||||
});
|
});
|
||||||
commands.insert_resource(CardImageSet {
|
commands.insert_resource(CardImageSet {
|
||||||
faces,
|
faces,
|
||||||
|
|||||||
@@ -1785,9 +1785,8 @@ mod tests {
|
|||||||
let layout = compute_layout(Vec2::new(1280.0, 800.0), 0.0, 0.0, true);
|
let layout = compute_layout(Vec2::new(1280.0, 800.0), 0.0, 0.0, true);
|
||||||
// Tableau 6 has 7 cards.
|
// Tableau 6 has 7 cards.
|
||||||
let (_, size) = pile_drop_rect(&PileType::Tableau(6), &layout, &game);
|
let (_, size) = pile_drop_rect(&PileType::Tableau(6), &layout, &game);
|
||||||
// Expected: card_height + 6 * fan. fan = 0.25 * card_height, so
|
// Expected: card_height + 6 fan steps.
|
||||||
// size.y = card_height * (1 + 6 * 0.25) = card_height * 2.5.
|
let expected = layout.card_size.y * (1.0 + 6.0 * layout.tableau_fan_frac);
|
||||||
let expected = layout.card_size.y * 2.5;
|
|
||||||
assert!(
|
assert!(
|
||||||
(size.y - expected).abs() < 1e-3,
|
(size.y - expected).abs() < 1e-3,
|
||||||
"expected {expected}, got {}",
|
"expected {expected}, got {}",
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ const VERTICAL_GAP_FRAC: f32 = 0.2;
|
|||||||
/// column must fit at this fraction). On desktop (height-limited) windows the
|
/// column must fit at this fraction). On desktop (height-limited) windows the
|
||||||
/// adaptive computation returns this value exactly; on portrait phones it
|
/// adaptive computation returns this value exactly; on portrait phones it
|
||||||
/// expands to fill available vertical space.
|
/// expands to fill available vertical space.
|
||||||
const TABLEAU_FAN_FRAC: f32 = 0.25;
|
const TABLEAU_FAN_FRAC: f32 = 0.18;
|
||||||
|
|
||||||
/// Minimum fraction for face-down tableau cards. Scales proportionally with
|
/// Minimum fraction for face-down tableau cards. Scales proportionally with
|
||||||
/// the adaptive face-up fraction so hit-testing and rendering stay in sync.
|
/// the adaptive face-up fraction so hit-testing and rendering stay in sync.
|
||||||
@@ -84,7 +84,7 @@ const TABLEAU_FAN_FRAC: f32 = 0.25;
|
|||||||
/// enough of each card back to read as a meaningful stack rather than a
|
/// enough of each card back to read as a meaningful stack rather than a
|
||||||
/// thin sliver. The ratio to TABLEAU_FAN_FRAC (0.80) is preserved by
|
/// thin sliver. The ratio to TABLEAU_FAN_FRAC (0.80) is preserved by
|
||||||
/// the adaptive scaling in `compute_layout`.
|
/// the adaptive scaling in `compute_layout`.
|
||||||
const TABLEAU_FACEDOWN_FAN_FRAC: f32 = 0.20;
|
const TABLEAU_FACEDOWN_FAN_FRAC: f32 = 0.14;
|
||||||
|
|
||||||
/// Largest possible face-up tableau column in Klondike: a King down to an Ace
|
/// Largest possible face-up tableau column in Klondike: a King down to an Ace
|
||||||
/// after every face-down card has flipped on column 7. Layout sizing must keep
|
/// after every face-down card has flipped on column 7. Layout sizing must keep
|
||||||
|
|||||||
Reference in New Issue
Block a user