From 19b6c9b6675914988df49493b4f6b6a5ecb5e15c Mon Sep 17 00:00:00 2001 From: The-Big-Mini Date: Wed, 1 Jul 2026 04:40:23 +0000 Subject: [PATCH 1/4] =?UTF-8?q?fix(auth):=20rebrand=20How=20It=20Works=20i?= =?UTF-8?q?nstructions=20SideStore=20=E2=86=92=20MiniStore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The How It Works onboarding screen still referred to SideStore in all four step strings. Rebrand the visible copy to MiniStore. VPN wording is left untouched (the sanctioned LocalDevVPN redirect flow). https://claude.ai/code/session_01PT8zpkUrgTRaGeKmbvVyNe --- AltStore/Authentication/InstructionsView.swift | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/AltStore/Authentication/InstructionsView.swift b/AltStore/Authentication/InstructionsView.swift index f661d22f..d26d1258 100644 --- a/AltStore/Authentication/InstructionsView.swift +++ b/AltStore/Authentication/InstructionsView.swift @@ -23,17 +23,17 @@ struct InstructionsView: View { private let steps: [Step] = [ Step(id: 1, - title: NSLocalizedString("Launch SideStore", comment: ""), - detail: NSLocalizedString("Leave SideStore running in the background on your idevice.", comment: "")), + title: NSLocalizedString("Launch MiniStore", comment: ""), + detail: NSLocalizedString("Leave MiniStore running in the background on your idevice.", comment: "")), Step(id: 2, title: NSLocalizedString("Connect to Wi-Fi and VPN", comment: ""), - detail: NSLocalizedString("Enable LocalDevVPN and use Sidestore on the go.", comment: "")), + detail: NSLocalizedString("Enable LocalDevVPN and use MiniStore on the go.", comment: "")), Step(id: 3, title: NSLocalizedString("Download Apps", comment: ""), - detail: NSLocalizedString("Browse and download apps directly from SideStore.", comment: "")), + detail: NSLocalizedString("Browse and download apps directly from MiniStore.", comment: "")), Step(id: 4, title: NSLocalizedString("Apps Refresh Automatically", comment: ""), - detail: NSLocalizedString("Apps are refreshed in the background while you are on SideStore VPN!", comment: "")), + detail: NSLocalizedString("Apps are refreshed in the background while you are on MiniStore VPN!", comment: "")), ] // Device-fixed: true only on screens under 600 pt tall (e.g. iPhone SE 1st gen). From 644542b0ee2ec3fb1c898bdca66325cd3388baa4 Mon Sep 17 00:00:00 2001 From: The-Big-Mini Date: Wed, 1 Jul 2026 04:40:55 +0000 Subject: [PATCH 2/4] fix(detail): enlarge floating back button to 44pt tap target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The App Detail and Source Detail screens draw their own floating back button (a circular glyph over the artwork). It was a 40x40 circle with a body-weight chevron — under Apple's 44pt minimum touch target and hard to hit. Bump the circle to 44x44 and the chevron to title3 so it is easier to press. backButtonSize (used in the banner-zone layout math) tracks the new size on both screens. https://claude.ai/code/session_01PT8zpkUrgTRaGeKmbvVyNe --- AltStore/App Detail/AppDetailView.swift | 6 +++--- AltStore/Sources/SourceDetailView.swift | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/AltStore/App Detail/AppDetailView.swift b/AltStore/App Detail/AppDetailView.swift index 5159fab4..00bbf2bc 100644 --- a/AltStore/App Detail/AppDetailView.swift +++ b/AltStore/App Detail/AppDetailView.swift @@ -145,7 +145,7 @@ struct AppDetailView: View { private let inset: CGFloat = 15 private let padding: CGFloat = 20 private let bannerHeight: CGFloat = AppBannerView.standardHeight - private let backButtonSize: CGFloat = 40 + private let backButtonSize: CGFloat = 44 var body: some View { GeometryReader { geo in @@ -443,9 +443,9 @@ struct AppDetailView: View { return HStack { SwiftUI.Button(action: { model.pop() }) { Image(systemName: "chevron.backward") - .font(.body.weight(.semibold)) + .font(.title3.weight(.semibold)) .foregroundStyle(Color(uiColor: model.app.tintColor ?? .altPrimary)) - .frame(width: 40, height: 40) + .frame(width: 44, height: 44) .background(.ultraThinMaterial, in: Circle()) } .accessibilityLabel(NSLocalizedString("Back", comment: "")) diff --git a/AltStore/Sources/SourceDetailView.swift b/AltStore/Sources/SourceDetailView.swift index 7961e190..976fa4f3 100644 --- a/AltStore/Sources/SourceDetailView.swift +++ b/AltStore/Sources/SourceDetailView.swift @@ -319,7 +319,7 @@ struct SourceDetailView: View { GeometryReader { geo in let width = geo.size.width let safeTop = geo.safeAreaInsets.top - let backButtonSize: CGFloat = 40 + let backButtonSize: CGFloat = 44 let minContentHeight = safeTop + backButtonSize + 8 + headerHeight + DetailLayout.padding let maxContentY = max(width * 0.667, minContentHeight) @@ -566,9 +566,9 @@ struct SourceDetailView: View { model.hostViewController?.navigationController?.popViewController(animated: true) } label: { Image(systemName: "chevron.backward") - .font(.body.weight(.semibold)) + .font(.title3.weight(.semibold)) .foregroundStyle(Color(uiColor: source.effectiveTintColor?.adjustedForDisplay ?? .altPrimary)) - .frame(width: 40, height: 40) + .frame(width: 44, height: 44) .background(.ultraThinMaterial, in: Circle()) } .accessibilityLabel(NSLocalizedString("Back", comment: "")) From 0e256981dd8faa629dc35698797224a8acc049ae Mon Sep 17 00:00:00 2001 From: The-Big-Mini Date: Wed, 1 Jul 2026 04:42:56 +0000 Subject: [PATCH 3/4] fix(app-detail): uniform aspect-fill screenshots, clip carousel to card Two carousel issues on the App Detail page: - Black bars: thumbnails were framed to each screenshot's own metadata aspect ratio, so a screenshot whose real image differs from that ratio (or carries baked-in letterbox padding) showed bars even with scaledToFill. Frame every thumbnail to one uniform modern-iPhone portrait ratio and aspect-fill it, so off-ratio content crops to fill instead of letterboxing. A shared width also makes the viewAligned carousel snap cleanly. - Scroll-off: give the horizontal carousel its own .clipped() band so thumbnails can't bleed past the rounded content card during a scroll/overscroll. The fullscreen preview carousel keeps per-image sizing (it should show the whole screenshot, not a cropped fill). https://claude.ai/code/session_01PT8zpkUrgTRaGeKmbvVyNe --- AltStore/App Detail/AppDetailView.swift | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/AltStore/App Detail/AppDetailView.swift b/AltStore/App Detail/AppDetailView.swift index 00bbf2bc..2697177f 100644 --- a/AltStore/App Detail/AppDetailView.swift +++ b/AltStore/App Detail/AppDetailView.swift @@ -597,6 +597,9 @@ private struct AppScreenshotsRow: View { } .scrollTargetBehavior(.viewAligned) .frame(height: 400) + // Clip the carousel to its own band so thumbnails never bleed past the rounded + // content card during a scroll/overscroll (they "scrolled off" the card edges). + .clipped() .padding(.bottom, 20) } } @@ -606,12 +609,13 @@ private struct DetailScreenshotView: View { private let preferredHeight: CGFloat = 400 - private var aspectRatio: CGFloat { - var r = screenshot.aspectRatio - if r.width > r.height && screenshot.deviceType == .iphone { - r = CGSize(width: r.height, height: r.width) - } - return r.width / r.height + // Uniform display aspect: every thumbnail is framed to the same modern-iPhone + // portrait ratio and aspect-FILLED (scaledToFill + clipped below), so screenshots + // whose real aspect differs from the frame — including any letterbox padding baked + // into the source image — crop to fill instead of showing black bars. A single shared + // width also lets the viewAligned carousel snap cleanly with no per-image width jitter. + private var frameWidth: CGFloat { + preferredHeight * (AppScreenshot.defaultAspectRatio.width / AppScreenshot.defaultAspectRatio.height) } @State private var image: UIImage? @@ -623,13 +627,13 @@ private struct DetailScreenshotView: View { Image(uiImage: img) .resizable() .scaledToFill() - .frame(width: preferredHeight * aspectRatio, height: preferredHeight) + .frame(width: frameWidth, height: preferredHeight) .clipped() } else { ProgressView() } } - .frame(width: preferredHeight * aspectRatio, height: preferredHeight) + .frame(width: frameWidth, height: preferredHeight) .clipShape(RoundedRectangle(cornerRadius: 5, style: .continuous)) .overlay( RoundedRectangle(cornerRadius: 5, style: .continuous) From 628c68debc5246c9c6157de05c85f83cddbe8587 Mon Sep 17 00:00:00 2001 From: The-Big-Mini Date: Wed, 1 Jul 2026 04:44:13 +0000 Subject: [PATCH 4/4] fix(my-apps): larger, symmetric section-header action buttons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The My Apps section-header buttons (Refresh All, and the Inactive info button) were small subheadline labels with only their glyph as the tap target, so they were fiddly to press. Two changes: - Extend each button's hit area toward the title and vertically (padding + contentShape) without moving the visible glyph, so it is easier to tap. - Reserve the Refresh All label's footprint in a ZStack while it spins, so the header's trailing edge no longer jumps when the spinner swaps in — the control stays symmetric across the idle and refreshing states. https://claude.ai/code/session_01PT8zpkUrgTRaGeKmbvVyNe --- AltStore/My Apps/MyAppsView.swift | 36 ++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/AltStore/My Apps/MyAppsView.swift b/AltStore/My Apps/MyAppsView.swift index 80a9a9bd..fbb15a46 100644 --- a/AltStore/My Apps/MyAppsView.swift +++ b/AltStore/My Apps/MyAppsView.swift @@ -460,17 +460,30 @@ private struct MyAppsSectionHeader: View { SwiftUI.Button { onButton() } label: { - if isSpinning { - ProgressView() - .tint(Color(.altPrimary)) - .accessibilityLabel(NSLocalizedString("Refreshing", comment: "")) - } else { - // foregroundStyle, not .tint: .tint does not color plain-style - // button text, so the accent never reached these labels. + ZStack { + // Reserve the idle title's footprint (kept in the layout, just + // hidden) so the header's trailing edge doesn't shift when the + // spinner swaps in — the button stays symmetric across the + // idle/refreshing states. Text(bt) - .font(.subheadline) - .foregroundStyle(Color(.altPrimary)) + .font(.subheadline.weight(.semibold)) + .opacity(isSpinning ? 0 : 1) + .accessibilityHidden(isSpinning) + if isSpinning { + ProgressView() + .controlSize(.small) + .tint(Color(.altPrimary)) + .accessibilityLabel(NSLocalizedString("Refreshing", comment: "")) + } } + // foregroundStyle, not .tint: .tint does not color plain-style + // button text, so the accent never reached these labels. + .foregroundStyle(Color(.altPrimary)) + // Extend the hit area toward the title and vertically without moving + // the glyph, so the small label is easier to press. + .padding(.vertical, 8) + .padding(.leading, 16) + .contentShape(Rectangle()) } .buttonStyle(.plain) } else if let icon = buttonIcon { @@ -478,8 +491,11 @@ private struct MyAppsSectionHeader: View { onButton() } label: { Image(systemName: icon) - .font(.subheadline) + .font(.subheadline.weight(.semibold)) .foregroundStyle(Color(.altPrimary)) + .padding(.vertical, 8) + .padding(.leading, 16) + .contentShape(Rectangle()) } .buttonStyle(.plain) }