From 0e73234418b5db5bc5f6eaa1e6f502da0fd20880 Mon Sep 17 00:00:00 2001 From: talksik Date: Tue, 14 Dec 2021 15:26:00 -0800 Subject: [PATCH] adding in functionality to use images with url links --- nirvana-ios.xcodeproj/project.pbxproj | 4 ++ nirvana-ios/Globals/RemoteImage.swift | 74 ++++++++++++++++++++ nirvana-ios/Views/HomeView/HomeView.swift | 2 +- nirvana-ios/Views/Templates/HeaderView.swift | 20 +++--- 4 files changed, 88 insertions(+), 12 deletions(-) create mode 100644 nirvana-ios/Globals/RemoteImage.swift diff --git a/nirvana-ios.xcodeproj/project.pbxproj b/nirvana-ios.xcodeproj/project.pbxproj index 6ba0b2b..96d23fc 100644 --- a/nirvana-ios.xcodeproj/project.pbxproj +++ b/nirvana-ios.xcodeproj/project.pbxproj @@ -31,6 +31,7 @@ 89288EC9276756DF00E962C4 /* FirebaseStorage in Frameworks */ = {isa = PBXBuildFile; productRef = 89288EC8276756DF00E962C4 /* FirebaseStorage */; }; 89288ECB27675B9F00E962C4 /* OnboardingTemplateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89288ECA27675B9F00E962C4 /* OnboardingTemplateView.swift */; }; 89B46E71276893E200B74255 /* AuthSessionStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89B46E70276893E200B74255 /* AuthSessionStore.swift */; }; + 89BDCDE527695DB900577829 /* RemoteImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89BDCDE427695DB900577829 /* RemoteImage.swift */; }; 89D99D2E2766FD6B00237814 /* Liquid in Frameworks */ = {isa = PBXBuildFile; productRef = 89D99D2D2766FD6B00237814 /* Liquid */; }; 89F1386D2767EB19006680ED /* SignInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89F1386C2767EB19006680ED /* SignInView.swift */; }; 89F138702767F55F006680ED /* GoogleSignIn in Frameworks */ = {isa = PBXBuildFile; productRef = 89F1386F2767F55F006680ED /* GoogleSignIn */; }; @@ -59,6 +60,7 @@ 89288EBF276755DF00E962C4 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 89288ECA27675B9F00E962C4 /* OnboardingTemplateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingTemplateView.swift; sourceTree = ""; }; 89B46E70276893E200B74255 /* AuthSessionStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthSessionStore.swift; sourceTree = ""; }; + 89BDCDE427695DB900577829 /* RemoteImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteImage.swift; sourceTree = ""; }; 89F1386C2767EB19006680ED /* SignInView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignInView.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -174,6 +176,7 @@ children = ( 891A15F4276557AB00B26659 /* colors.swift */, 891A15FC276566B800B26659 /* constants.swift */, + 89BDCDE427695DB900577829 /* RemoteImage.swift */, ); path = Globals; sourceTree = ""; @@ -314,6 +317,7 @@ 89B46E71276893E200B74255 /* AuthSessionStore.swift in Sources */, 891A15F9276563CA00B26659 /* WelcomeView.swift in Sources */, 891A1611276590B000B26659 /* ChatsCarouselView.swift in Sources */, + 89BDCDE527695DB900577829 /* RemoteImage.swift in Sources */, 891A16132765A44300B26659 /* ChatsCarouselViewModel.swift in Sources */, 891A15E127653A7000B26659 /* nirvana_iosApp.swift in Sources */, 891A160127656FB200B26659 /* FooterView.swift in Sources */, diff --git a/nirvana-ios/Globals/RemoteImage.swift b/nirvana-ios/Globals/RemoteImage.swift new file mode 100644 index 0000000..f2b9dc9 --- /dev/null +++ b/nirvana-ios/Globals/RemoteImage.swift @@ -0,0 +1,74 @@ +// +// RemoteImage.swift +// nirvana-ios +// +// Created by Arjun Patel on 12/14/21. +// + +import SwiftUI + +struct RemoteImage: View { + private enum LoadState { + case loading, success, failure + } + + private class Loader: ObservableObject { + var data = Data() + var state = LoadState.loading + + init(url: String) { + guard let parsedURL = URL(string: url) else { + fatalError("Invalid URL: \(url)") + } + + URLSession.shared.dataTask(with: parsedURL) { data, response, error in + if let data = data, data.count > 0 { + self.data = data + self.state = .success + } else { + self.state = .failure + } + + DispatchQueue.main.async { + self.objectWillChange.send() + } + }.resume() + } + } + + @StateObject private var loader: Loader + var loading: Image + var failure: Image + + var body: some View { + selectImage() + .resizable() + } + + init(url: String, loading: Image = Image(systemName: "photo"), failure: Image = Image(systemName: "multiply.circle")) { + _loader = StateObject(wrappedValue: Loader(url: url)) + self.loading = loading + self.failure = failure + } + + private func selectImage() -> Image { + switch loader.state { + case .loading: + return loading + case .failure: + return failure + default: + if let image = UIImage(data: loader.data) { + return Image(uiImage: image) + } else { + return failure + } + } + } +} + +struct RemoteImage_Previews: PreviewProvider { + static var previews: some View { + RemoteImage(url: "https://avatars.githubusercontent.com/u/41487836") + } +} diff --git a/nirvana-ios/Views/HomeView/HomeView.swift b/nirvana-ios/Views/HomeView/HomeView.swift index 7740183..2d824dc 100644 --- a/nirvana-ios/Views/HomeView/HomeView.swift +++ b/nirvana-ios/Views/HomeView/HomeView.swift @@ -10,7 +10,7 @@ import SwiftUI struct HomeView: View { var body: some View { VStack(alignment: .leading, spacing: 0) { - HeaderView(isAuth:true) + HeaderView() ChatsCarouselView() diff --git a/nirvana-ios/Views/Templates/HeaderView.swift b/nirvana-ios/Views/Templates/HeaderView.swift index 472e158..6c2a6df 100644 --- a/nirvana-ios/Views/Templates/HeaderView.swift +++ b/nirvana-ios/Views/Templates/HeaderView.swift @@ -8,15 +8,11 @@ import SwiftUI struct HeaderView: View { - var isAuthenticated:Bool = false - - init(isAuth:Bool = false) { - self.isAuthenticated = isAuth - } + @EnvironmentObject var authStore:AuthSessionStore var body: some View { HStack(alignment:.center) { - if (self.isAuthenticated) { + if self.authStore.sessionState == SessionState.isAuthenticated { Image(systemName: "list.bullet.circle") .font(Font.system(.largeTitle)) .padding() @@ -38,11 +34,13 @@ struct HeaderView: View { Spacer() - if (self.isAuthenticated) { - Image(systemName: "person.crop.circle.badge.plus") - .font(Font.system(.largeTitle)) + if self.authStore.sessionState == SessionState.isAuthenticated { + RemoteImage(url: "https://avatars.githubusercontent.com/u/41487836") + .background(NirvanaColor.teal) + .aspectRatio(contentMode: .fit) + .frame(width: 40, height: 40) + .clipShape(Circle()) .padding() - .foregroundColor(NirvanaColor.teal) } } .frame(maxWidth: .infinity) @@ -51,6 +49,6 @@ struct HeaderView: View { struct HeaderView_Previews: PreviewProvider { static var previews: some View { - HeaderView(isAuth:true) + HeaderView().environmentObject(AuthSessionStore()) } }