fix(android): resolve local asset image resource loading using asyncimage and bundle url

This commit is contained in:
Daniel Arantes Loverde
2026-05-27 15:01:49 -03:00
parent c14bd7a928
commit 215d208f4f
24 changed files with 103 additions and 36 deletions

View File

@@ -96,12 +96,18 @@ struct FeaturedStoreCard: View {
private var storeIconPlaceholder: some View {
ZStack {
#if os(Android)
Image("placeholder-product", bundle: .module)
.resizable()
.scaledToFill()
.opacity(0.7)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.clipped()
AsyncImage(url: Bundle.module.url(forResource: "placeholder-product", withExtension: "png")) { phase in
if let image = phase.image {
image
.resizable()
} else {
Color.clear
}
}
.scaledToFill()
.opacity(0.7)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.clipped()
#else
Image("placeholder-product")
.resizable()

View File

@@ -7,7 +7,8 @@ import AppKit
// MARK: - Colors
enum AppColors {
struct AppColors {
private init() {}
// Brandbook 2026 (Pedi Foods)
// Primary now follows the "FOODS" dark green tone from the logo.
static let primary = Color(.sRGB, red: 52/255.0, green: 93/255.0, blue: 84/255.0, opacity: 1.0)
@@ -26,7 +27,8 @@ enum AppColors {
static let textMuted = Color(.sRGB, red: 102/255.0, green: 112/255.0, blue: 133/255.0, opacity: 1.0)
}
enum AppDarkColors {
struct AppDarkColors {
private init() {}
static let background = Color(.sRGB, red: 31/255.0, green: 45/255.0, blue: 64/255.0, opacity: 1.0)
static let surface = Color.white.opacity(0.08)
static let textPrimary = Color.white
@@ -38,7 +40,8 @@ enum AppDarkColors {
// MARK: - Typography
enum AppTypography {
struct AppTypography {
private init() {}
// Brandbook typography: Nexa (fallback: system font)
static let fontFamily = "Nexa-Regular"
@@ -75,7 +78,8 @@ enum AppTypography {
// MARK: - Layout
enum AppLayout {
struct AppLayout {
private init() {}
static let radiusMD: CGFloat = 12
static let radiusLG: CGFloat = 16
static let radiusXL: CGFloat = 24
@@ -92,7 +96,8 @@ struct ShadowSpec {
let y: CGFloat
}
enum AppShadow {
struct AppShadow {
private init() {}
static let soft = ShadowSpec(color: Color.black.opacity(0.08), radius: 20, y: 6)
static let glow = ShadowSpec(color: AppColors.tertiary.opacity(0.2), radius: 24, y: 8)
}

View File

@@ -15,8 +15,14 @@ struct LoginEmailView: View {
@ViewBuilder private var logoImage: some View {
#if os(Android)
SwiftUI.Image("pedifoods", bundle: .module)
.resizable()
AsyncImage(url: Bundle.module.url(forResource: "pedifoods", withExtension: "png")) { phase in
if let image = phase.image {
image
.resizable()
} else {
Color.clear
}
}
#else
SwiftUI.Image("pedifoods")
.resizable()

View File

@@ -16,8 +16,14 @@ struct LoginView: View {
@ViewBuilder private var logoImage: some View {
#if os(Android)
SwiftUI.Image("pedifoods", bundle: .module)
.resizable()
AsyncImage(url: Bundle.module.url(forResource: "pedifoods", withExtension: "png")) { phase in
if let image = phase.image {
image
.resizable()
} else {
Color.clear
}
}
#else
SwiftUI.Image("pedifoods")
.resizable()
@@ -26,8 +32,14 @@ struct LoginView: View {
@ViewBuilder private var pinHeroImage: some View {
#if os(Android)
SwiftUI.Image(colorScheme == .dark ? "pin_image_app_dark" : "pin_image_app", bundle: .module)
.resizable()
AsyncImage(url: Bundle.module.url(forResource: colorScheme == .dark ? "pin_image_app_dark" : "pin_image_app", withExtension: "png")) { phase in
if let image = phase.image {
image
.resizable()
} else {
Color.clear
}
}
#else
SwiftUI.Image("pin_image_app")
.resizable()

View File

@@ -26,11 +26,17 @@ struct OtpView: View {
ScrollView {
VStack(spacing: 0) {
#if os(Android)
SwiftUI.Image("pedifoods", bundle: .module)
.resizable()
.scaledToFit()
.frame(width: 74, height: 74)
.padding(.top, 140)
AsyncImage(url: Bundle.module.url(forResource: "pedifoods", withExtension: "png")) { phase in
if let image = phase.image {
image
.resizable()
} else {
Color.clear
}
}
.scaledToFit()
.frame(width: 74, height: 74)
.padding(.top, 140)
#else
SwiftUI.Image("pedifoods")
.resizable()

View File

@@ -19,8 +19,14 @@ struct RegistrationView: View {
@ViewBuilder private var logoImage: some View {
#if os(Android)
SwiftUI.Image("pedifoods", bundle: .module)
.resizable()
AsyncImage(url: Bundle.module.url(forResource: "pedifoods", withExtension: "png")) { phase in
if let image = phase.image {
image
.resizable()
} else {
Color.clear
}
}
#else
SwiftUI.Image("pedifoods")
.resizable()

View File

@@ -37,8 +37,14 @@ struct LaunchSplashView: View {
@ViewBuilder var splashLogo: some View {
#if os(Android)
SwiftUI.Image("pedifoods", bundle: .module)
.resizable()
AsyncImage(url: Bundle.module.url(forResource: "pedifoods", withExtension: "png")) { phase in
if let image = phase.image {
image
.resizable()
} else {
Color.clear
}
}
#else
SwiftUI.Image("pedifoods")
.resizable()

View File

@@ -33,8 +33,14 @@ struct AddAddressFormView: View {
@ViewBuilder private var logoImage: some View {
#if os(Android)
SwiftUI.Image("pedifoods", bundle: .module)
.resizable()
AsyncImage(url: Bundle.module.url(forResource: "pedifoods", withExtension: "png")) { phase in
if let image = phase.image {
image
.resizable()
} else {
Color.clear
}
}
#else
SwiftUI.Image("pedifoods")
.resizable()

View File

@@ -223,10 +223,16 @@ struct OrderTrackingView: View {
Group {
if hasTrackingImage {
#if os(Android)
Image(trackingImageName, bundle: .module)
.renderingMode(.original)
.resizable()
.scaledToFit()
AsyncImage(url: Bundle.module.url(forResource: trackingImageName, withExtension: "png")) { phase in
if let image = phase.image {
image
.renderingMode(.original)
.resizable()
} else {
Color.clear
}
}
.scaledToFit()
#else
Image(trackingImageName)
.renderingMode(.original)
@@ -235,10 +241,16 @@ struct OrderTrackingView: View {
#endif
} else if hasPlaceholderProductImage {
#if os(Android)
Image("placeholder-product", bundle: .module)
.renderingMode(.original)
.resizable()
.scaledToFit()
AsyncImage(url: Bundle.module.url(forResource: "placeholder-product", withExtension: "png")) { phase in
if let image = phase.image {
image
.renderingMode(.original)
.resizable()
} else {
Color.clear
}
}
.scaledToFit()
#else
Image("placeholder-product")
.renderingMode(.original)