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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 924 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 951 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 940 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 926 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 799 KiB

View File

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

View File

@@ -7,7 +7,8 @@ import AppKit
// MARK: - Colors // MARK: - Colors
enum AppColors { struct AppColors {
private init() {}
// Brandbook 2026 (Pedi Foods) // Brandbook 2026 (Pedi Foods)
// Primary now follows the "FOODS" dark green tone from the logo. // 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) 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) 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 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 surface = Color.white.opacity(0.08)
static let textPrimary = Color.white static let textPrimary = Color.white
@@ -38,7 +40,8 @@ enum AppDarkColors {
// MARK: - Typography // MARK: - Typography
enum AppTypography { struct AppTypography {
private init() {}
// Brandbook typography: Nexa (fallback: system font) // Brandbook typography: Nexa (fallback: system font)
static let fontFamily = "Nexa-Regular" static let fontFamily = "Nexa-Regular"
@@ -75,7 +78,8 @@ enum AppTypography {
// MARK: - Layout // MARK: - Layout
enum AppLayout { struct AppLayout {
private init() {}
static let radiusMD: CGFloat = 12 static let radiusMD: CGFloat = 12
static let radiusLG: CGFloat = 16 static let radiusLG: CGFloat = 16
static let radiusXL: CGFloat = 24 static let radiusXL: CGFloat = 24
@@ -92,7 +96,8 @@ struct ShadowSpec {
let y: CGFloat 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 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) 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 { @ViewBuilder private var logoImage: some View {
#if os(Android) #if os(Android)
SwiftUI.Image("pedifoods", bundle: .module) AsyncImage(url: Bundle.module.url(forResource: "pedifoods", withExtension: "png")) { phase in
if let image = phase.image {
image
.resizable() .resizable()
} else {
Color.clear
}
}
#else #else
SwiftUI.Image("pedifoods") SwiftUI.Image("pedifoods")
.resizable() .resizable()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

1
pedi-foods/Vendor/skip-fuse-ui vendored Submodule

Submodule pedi-foods/Vendor/skip-fuse-ui added at 9025fb50e2

1
pedi-foods/Vendor/skip-ui vendored Submodule

Submodule pedi-foods/Vendor/skip-ui added at 9d584e7096