Skip to content

Commit

Permalink
Fix group creation issue with image
Browse files Browse the repository at this point in the history
  • Loading branch information
cp-amisha-i committed Nov 25, 2024
1 parent 67c4429 commit 7c38436
Show file tree
Hide file tree
Showing 18 changed files with 345 additions and 130 deletions.
8 changes: 4 additions & 4 deletions BaseStyle/BaseStyle.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
/* Begin PBXBuildFile section */
213A1F2A2C52335D00BF9800 /* CheckmarkButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 213A1F292C52335D00BF9800 /* CheckmarkButton.swift */; };
213F377E2C416C9C00972316 /* ScrollToTopButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 213F377D2C416C9C00972316 /* ScrollToTopButton.swift */; };
214F00642CF0926A00A7EA9A /* ZoomableImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 214F00632CF0926A00A7EA9A /* ZoomableImageView.swift */; };
217620462C4F7CE700FED0D4 /* BackButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 217620452C4F7CE700FED0D4 /* BackButton.swift */; };
2176204A2C521EDF00FED0D4 /* RadioButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 217620492C521EDF00FED0D4 /* RadioButton.swift */; };
219F43D92CCA4A7000729C67 /* RestoreButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 219F43D82CCA4A7000729C67 /* RestoreButton.swift */; };
Expand Down Expand Up @@ -56,6 +55,7 @@
D8E244C12B986CD800C6C82A /* ImagePickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8E244C02B986CD800C6C82A /* ImagePickerView.swift */; };
D8E244C32B986D4F00C6C82A /* UIImage+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8E244C22B986D4F00C6C82A /* UIImage+Extension.swift */; };
D8EB0ED82CAD8C9F00AC6A44 /* ErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8EB0ED72CAD8C9F00AC6A44 /* ErrorView.swift */; };
D8FFD5C72CF44DBC009A0667 /* ZoomableImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8FFD5C62CF44DBC009A0667 /* ZoomableImageView.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand All @@ -72,7 +72,6 @@
174198EE4AF2FC82DADEB060 /* Pods_BaseStyle.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_BaseStyle.framework; sourceTree = BUILT_PRODUCTS_DIR; };
213A1F292C52335D00BF9800 /* CheckmarkButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckmarkButton.swift; sourceTree = "<group>"; };
213F377D2C416C9C00972316 /* ScrollToTopButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollToTopButton.swift; sourceTree = "<group>"; };
214F00632CF0926A00A7EA9A /* ZoomableImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZoomableImageView.swift; sourceTree = "<group>"; };
217620452C4F7CE700FED0D4 /* BackButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackButton.swift; sourceTree = "<group>"; };
217620492C521EDF00FED0D4 /* RadioButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButton.swift; sourceTree = "<group>"; };
219F43D82CCA4A7000729C67 /* RestoreButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RestoreButton.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -122,6 +121,7 @@
D8E244C02B986CD800C6C82A /* ImagePickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePickerView.swift; sourceTree = "<group>"; };
D8E244C22B986D4F00C6C82A /* UIImage+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+Extension.swift"; sourceTree = "<group>"; };
D8EB0ED72CAD8C9F00AC6A44 /* ErrorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorView.swift; sourceTree = "<group>"; };
D8FFD5C62CF44DBC009A0667 /* ZoomableImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZoomableImageView.swift; sourceTree = "<group>"; };
E0B1A6930B9FF35E9142463B /* Pods-BaseStyle.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BaseStyle.debug.xcconfig"; path = "Target Support Files/Pods-BaseStyle/Pods-BaseStyle.debug.xcconfig"; sourceTree = "<group>"; };
E4AFAF996FB5C233D40D81D5 /* Pods_BaseStyleTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_BaseStyleTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
Expand Down Expand Up @@ -274,7 +274,7 @@
21BEF8A42C637E4900FBC9CF /* NavigationBarTopView.swift */,
21D614782CAD527D00779F1E /* NavigationTitleTextView.swift */,
219F43D82CCA4A7000729C67 /* RestoreButton.swift */,
214F00632CF0926A00A7EA9A /* ZoomableImageView.swift */,
D8FFD5C62CF44DBC009A0667 /* ZoomableImageView.swift */,
);
path = Views;
sourceTree = "<group>";
Expand Down Expand Up @@ -506,7 +506,7 @@
D82174BE2BBAD86D00DB42C3 /* ProfileImageView.swift in Sources */,
213F377E2C416C9C00972316 /* ScrollToTopButton.swift in Sources */,
D89C933F2BC3C0F800FACD16 /* ForwardIcon.swift in Sources */,
214F00642CF0926A00A7EA9A /* ZoomableImageView.swift in Sources */,
D8FFD5C72CF44DBC009A0667 /* ZoomableImageView.swift in Sources */,
D89DBE352B88A05F00E5F1BD /* UIApplication+Extension.swift in Sources */,
D8D42A772B85CE2A009B345D /* ButtonStyleTapGestureModifier.swift in Sources */,
21BEF8A52C637E4900FBC9CF /* NavigationBarTopView.swift in Sources */,
Expand Down
87 changes: 80 additions & 7 deletions BaseStyle/BaseStyle/Views/ZoomableImageView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,87 @@
// ZoomableImageView.swift
// Splito
//
// Created by Nirali Sonani on 22/11/24.
// Created by Amisha Italiya on 25/11/24.
//

import SwiftUI
import Kingfisher

public struct ZoomableImageView: View {
// MARK: - ExpenseImageView

public struct ExpenseImageView: View {

@Binding var showImageDisplayView: Bool

var image: UIImage?
var imageUrl: String?

@Namespace private var animationNamespace

public var body: some View {
ZStack {
if let image {
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fill)
} else if let imageUrl, let url = URL(string: imageUrl) {
KFImage(url)
.placeholder { _ in
ImageLoaderView()
}
.setProcessor(DownsamplingImageProcessor(size: UIScreen.main.bounds.size)) // Downsample to fit screen size
.cacheMemoryOnly()
.resizable()
.aspectRatio(contentMode: .fill)
}
}
.matchedGeometryEffect(id: "image", in: animationNamespace)
.onTapGestureForced {
showImageDisplayView = true
}
}
}

// MARK: - ExpenseImageZoomView

public struct ExpenseImageZoomView: View {
@Environment(\.dismiss) var dismiss

var image: UIImage?
var imageUrl: String?

@Namespace var animationNamespace

public var body: some View {
GeometryReader { geometry in
ZStack {
if #available(iOS 18.0, *) {
ZoomableImageView(image: image, imageUrl: imageUrl, geometry: geometry)
.matchedGeometryEffect(id: "image", in: animationNamespace)
.navigationTransition(.zoom(sourceID: "zoom", in: animationNamespace))
} else {
ZoomableImageView(image: image, imageUrl: imageUrl, geometry: geometry)
}
}
}
.navigationBarBackButtonHidden()
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button {
dismiss()
} label: {
Image(systemName: "xmark.circle.fill")
.font(.system(size: 18))
.foregroundStyle(disableText)
}
}
}
}
}

// MARK: - ZoomableImageView

private struct ZoomableImageView: View {

var image: UIImage?
var imageUrl: String?
Expand All @@ -17,6 +91,7 @@ public struct ZoomableImageView: View {
@State var scale: CGFloat = 1
@State var scaleAnchor: UnitPoint = .center
@State var lastScale: CGFloat = 1

@State var offset: CGSize = .zero
@State var lastOffset: CGSize = .zero

Expand Down Expand Up @@ -57,9 +132,9 @@ public struct ZoomableImageView: View {
}
}

public var body: some View {
var body: some View {
ZStack {
if let image = image {
if let image {
Image(uiImage: image)
.resizable()
.scaledToFit()
Expand All @@ -73,7 +148,7 @@ public struct ZoomableImageView: View {
.simultaneousGesture(TapGesture(count: 2).onEnded({ _ in
resetZoom()
}))
} else if let imageUrl = imageUrl, let url = URL(string: imageUrl) {
} else if let imageUrl, let url = URL(string: imageUrl) {
KFImage(url)
.placeholder { _ in
ImageLoaderView()
Expand Down Expand Up @@ -124,13 +199,11 @@ public struct ZoomableImageView: View {

if imageWidth > screenSize.width {
let widthLimit: CGFloat = imageWidth > screenSize.width ? (imageWidth - screenSize.width) / 2 : 0

width = offset.width > 0 ? .minimum(widthLimit, offset.width) : .maximum(-widthLimit, offset.width)
}

if imageHeight > screenSize.height {
let heightLimit: CGFloat = imageHeight > screenSize.height ? (imageHeight - screenSize.height) / 2 : 0

height = offset.height > 0 ? .minimum(heightLimit, offset.height) : .maximum(-heightLimit, offset.height)
}

Expand Down
2 changes: 1 addition & 1 deletion Data/Data/Model/ActivityLog.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// ActivityLog.swift
// Data
//
// Created by Nirali Sonani on 14/10/24.
// Created by Amisha Italiya on 14/10/24.
//

import FirebaseFirestore
Expand Down
2 changes: 1 addition & 1 deletion Data/Data/Repository/ActivityLogRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// ActivityLogRepository.swift
// Data
//
// Created by Nirali Sonani on 14/10/24.
// Created by Amisha Italiya on 14/10/24.
//

import FirebaseFirestore
Expand Down
12 changes: 6 additions & 6 deletions Data/Data/Repository/ExpenseRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@ public class ExpenseRepository: ObservableObject {

public func addExpense(group: Groups, expense: Expense, imageData: Data?) async throws -> Expense {
// Generate a new document ID for the expense
let documentRef = store.expenseReference(groupId: group.id ?? "").document()
let expenseId = documentRef.documentID
let groupId = group.id ?? ""
let expenseDocument = try await store.getNewExpenseDocument(groupId: groupId)

var newExpense = expense
newExpense.id = expenseId
newExpense.id = expenseDocument.documentID

// If image data is provided, upload the image and update the expense's imageUrl
if let imageData = imageData {
if let imageData {
let imageUrl = try await uploadImage(imageData: imageData, expense: newExpense)
newExpense.imageUrl = imageUrl
}

try await store.addExpense(documentRef: documentRef, expense: newExpense)
try await store.addExpense(document: expenseDocument, expense: newExpense)
try await addActivityLogForExpense(group: group, expense: newExpense, oldExpense: newExpense, type: .expenseAdded)
return newExpense
}
Expand All @@ -53,7 +53,7 @@ public class ExpenseRepository: ObservableObject {
// If there's a current image URL and we want to remove it, delete the image and set imageUrl to nil
try await storageManager.deleteImage(imageUrl: currentUrl)
updatedExpense.imageUrl = nil
} else if let newImageUrl = newImageUrl {
} else if let newImageUrl {
// If a new image URL is explicitly passed, update it
updatedExpense.imageUrl = newImageUrl
}
Expand Down
5 changes: 3 additions & 2 deletions Data/Data/Repository/GroupRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,18 @@ public class GroupRepository: ObservableObject {
private let groupMembersQueue = DispatchQueue(label: "groupMembers.queue", attributes: .concurrent)

public func createGroup(group: Groups, imageData: Data?) async throws -> Groups {
let groupId = try await store.createGroup(group: group)
let groupDocument = try await store.getNewGroupDocument()

var newGroup = group
newGroup.id = groupId
newGroup.id = groupDocument.documentID

// If image data is provided, upload the image and update the group's imageUrl
if let imageData = imageData {
let imageUrl = try await uploadImage(imageData: imageData, group: newGroup)
newGroup.imageUrl = imageUrl
}

try await store.createGroup(document: groupDocument, group: newGroup)
try await logAddGroupActivity(group: newGroup, type: .groupCreated)

return newGroup
Expand Down
2 changes: 1 addition & 1 deletion Data/Data/Store/ActivityLogStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// ActivityLogStore.swift
// Data
//
// Created by Nirali Sonani on 14/10/24.
// Created by Amisha Italiya on 14/10/24.
//

import FirebaseFirestore
Expand Down
10 changes: 7 additions & 3 deletions Data/Data/Store/ExpenseStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,19 @@ public class ExpenseStore: ObservableObject {
private let COLLECTION_NAME: String = "groups"
private let SUB_COLLECTION_NAME: String = "expenses"

func expenseReference(groupId: String) -> CollectionReference {
private func expenseReference(groupId: String) -> CollectionReference {
database
.collection(COLLECTION_NAME)
.document(groupId)
.collection(SUB_COLLECTION_NAME)
}

func addExpense(documentRef: DocumentReference, expense: Expense) async throws {
try documentRef.setData(from: expense)
func getNewExpenseDocument(groupId: String) async throws -> DocumentReference {
return expenseReference(groupId: groupId).document()
}

func addExpense(document: DocumentReference, expense: Expense) async throws {
try document.setData(from: expense)
}

func updateExpense(groupId: String, expense: Expense) async throws {
Expand Down
19 changes: 11 additions & 8 deletions Data/Data/Store/GroupStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,36 @@ class GroupStore: ObservableObject {
@Inject private var database: Firestore
@Inject private var preference: SplitoPreference

private var groupsCollection: CollectionReference {
private var groupReference: CollectionReference {
database.collection(GroupStore.COLLECTION_NAME)
}

func createGroup(group: Groups) async throws -> String {
let documentRef = try groupsCollection.addDocument(from: group)
return documentRef.documentID
func getNewGroupDocument() async throws -> DocumentReference {
return groupReference.document()
}

func createGroup(document: DocumentReference, group: Groups) async throws {
try document.setData(from: group)
}

func addMemberToGroup(groupId: String, memberId: String) async throws {
// Wrap the updateData in a Task for async handling
try await groupsCollection.document(groupId).updateData([
try await groupReference.document(groupId).updateData([
"members": FieldValue.arrayUnion([memberId])
])
}

func updateGroup(group: Groups) async throws {
if let groupId = group.id {
try groupsCollection.document(groupId).setData(from: group, merge: false)
try groupReference.document(groupId).setData(from: group, merge: false)
} else {
LogE("GroupStore :: \(#function) Group not found.")
throw ServiceError.dataNotFound
}
}

func fetchGroupsBy(userId: String, limit: Int, lastDocument: DocumentSnapshot?) async throws -> (data: [Groups], lastDocument: DocumentSnapshot?) {
var query = groupsCollection
var query = groupReference
.whereField("is_active", isEqualTo: true)
.whereField("members", arrayContains: userId)
.order(by: "created_at", descending: true)
Expand All @@ -54,6 +57,6 @@ class GroupStore: ObservableObject {
}

func fetchGroupBy(id: String) async throws -> Groups? {
return try await groupsCollection.document(id).getDocument(as: Groups.self, source: .server)
return try await groupReference.document(id).getDocument(as: Groups.self, source: .server)
}
}
Loading

0 comments on commit 7c38436

Please sign in to comment.