add friend request

feature/friends-request
Lucas DELANIER 8 months ago
parent e32d032d3c
commit b8ba032ecc

@ -14,7 +14,7 @@ struct EmptyInfo: View {
var body: some View {
VStack{
Text(emoji).font(.system(size: 120))
Text(title).textStyle(weight: .bold, color: .black, size: 15)
Text(title).textStyle(weight: .bold, color: AllInColors.primaryTextColor , size: 15)
explain.isEmpty ? nil : Text(explain).textStyle(weight: .light, color: .gray, size: 12)
}.opacity(0.55).padding(.horizontal, 20).multilineTextAlignment(.center)
}

@ -11,14 +11,15 @@ import Model
struct Friend: View {
var user: User
let isRequest: Bool
@ObservedObject var viewModel: FriendsViewModel
var StatusValues: (String, Color, Color) {
switch user.friendStatus {
case .friend:
return (String(localized: "generic_delete"), AllInColors.grey400Color, AllInColors.componentBackgroundColor)
return isRequest ? (String(localized: "generic_decline"), AllInColors.grey400Color, AllInColors.componentBackgroundColor) : (String(localized: "generic_delete"), AllInColors.grey400Color, AllInColors.componentBackgroundColor)
case .notFriend:
return (String(localized: "generic_add"), .white, AllInColors.lightPurpleColor)
return isRequest ? (String(localized: "generic_acccept"), .white, AllInColors.lightPurpleColor) : (String(localized: "generic_add"), .white, AllInColors.lightPurpleColor)
case .requested:
return (String(localized: "friends_request_sent"), AllInColors.grey400Color, AllInColors.componentBackgroundColor)
default:
@ -39,7 +40,7 @@ struct Friend: View {
.lineLimit(1)
Spacer()
Button(StatusValues.0) {
viewModel.toggleFriendStatus(for: user)
viewModel.toggleFriendStatus(for: user, isRequest: isRequest)
}
.minimumScaleFactor(0.3)
.lineLimit(2)
@ -48,6 +49,13 @@ struct Friend: View {
.font(.system(size: 14))
.background(StatusValues.2)
.cornerRadius(5)
if(isRequest){
Button{
viewModel.declineRequest(username: user.username)
}label: {
Image(systemName: "xmark").foregroundColor(.gray)
}.padding([.leading], 25)
}
}
.padding([.trailing,.leading], 25)
}

@ -21,6 +21,8 @@
"generic_in_waiting" = "In waiting";
"generic_search" = "Search";
"generic_add" = "Add";
"generic_acccept"="Accept";
"generic_decline"="Decline";
"generic_delete" = "Delete";
"generic_stake" = "Stake";
"network_error_text" = "Make sure to be properly connected to the network then try again.";
@ -167,6 +169,7 @@
"friends_title" = "Friends";
"friends_request_sent" = "Request sent";
"friends_request"= "Friends Request";
/// Daily reward

@ -21,6 +21,8 @@
"generic_in_waiting" = "En attente";
"generic_search" = "Rechercher";
"generic_add" = "Ajouter";
"generic_acccept"="Accepter";
"generic_decline"="Decliner";
"generic_delete" = "Supprimer";
"generic_stake" = "Mise";
"network_error_text" = "Assurez-vous d\'être bien connecté au réseau puis réessayez.";
@ -167,6 +169,7 @@
"friends_title" = "Amis";
"friends_request_sent" = "Requête envoyée";
"friends_request"= "Requêtes d'amis";
/// Daily reward

@ -14,6 +14,7 @@ class FriendsViewModel: ObservableObject {
@Inject var manager: Manager
@Published private(set) var users: [User] = []
@Published private(set) var requests: [User] = []
@Published var text: String = "" {
didSet {
if text.isEmpty {
@ -26,6 +27,7 @@ class FriendsViewModel: ObservableObject {
init() {
getItems()
getRequests()
}
func getItems() {
@ -36,6 +38,14 @@ class FriendsViewModel: ObservableObject {
}
}
func getRequests() {
manager.getRequests() { friends in
DispatchQueue.main.async {
self.requests = friends
}
}
}
func search() {
guard text.allSatisfy({ $0.isLetter || $0.isNumber }) else {
return
@ -46,26 +56,48 @@ class FriendsViewModel: ObservableObject {
}
}
func toggleFriendStatus(for user: User) {
guard let index = users.firstIndex(where: { $0.username == user.username }) else { return }
var updatedUser = users[index]
func toggleFriendStatus(for user: User, isRequest: Bool) {
let targetList = isRequest ? requests : users
switch updatedUser.friendStatus {
case .friend:
updatedUser.friendStatus = .notFriend
deleteItem(username: user.username)
case .notFriend:
updatedUser.friendStatus = .requested
addItem(username: user.username)
case .requested:
updatedUser.friendStatus = .notFriend
deleteItem(username: user.username)
default:
break
}
guard let index = targetList.firstIndex(where: { $0.username == user.username }) else { return }
var updatedUser = targetList[index]
users[index] = updatedUser
if isRequest {
if updatedUser.friendStatus == .requested {
updatedUser.friendStatus = .notFriend
deleteItem(username: user.username)
} else {
updatedUser.friendStatus = .friend
addItem(username: user.username)
}
requests.remove(at: index)
} else {
switch updatedUser.friendStatus {
case .friend:
updatedUser.friendStatus = .notFriend
deleteItem(username: user.username)
case .notFriend:
updatedUser.friendStatus = .requested
addItem(username: user.username)
case .requested:
updatedUser.friendStatus = .notFriend
deleteItem(username: user.username)
default:
break
}
users[index] = updatedUser
}
}
func declineRequest(username: String){
guard let index = requests.firstIndex(where: { $0.username == username }) else { return }
manager.removeFriend(withUsername: username) { statusCode in
}
requests.remove(at: index)
}
func deleteItem(username: String) {
manager.removeFriend(withUsername: username) { statusCode in

@ -11,52 +11,105 @@ struct FriendsView: View {
@StateObject private var viewModel = FriendsViewModel()
@Binding var showMenu: Bool
@State private var selectedTab = 0
var body: some View {
VStack(alignment: .center, spacing: 0) {
TopBar(showMenu: self.$showMenu)
Text("friends_title")
.textStyle(weight: .bold, color: AllInColors.grey500Color, size: 25)
.padding([.top,.bottom],15)
HStack {
TextField("Search...", text: $viewModel.text)
.padding(7)
.padding(.horizontal, 25)
.background(Color(.systemGray6))
.cornerRadius(8)
.overlay(
TabView(selection: $selectedTab) {
ScrollView(showsIndicators: false){
VStack{
HStack {
Image(systemName: "magnifyingglass")
.foregroundColor(.gray)
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
.padding(.leading, 8)
TextField("Search...", text: $viewModel.text)
.padding(7)
.zIndex(200)
.padding(.horizontal, 25)
.background(Color(.systemGray6))
.cornerRadius(8)
.overlay(
HStack {
Image(systemName: "magnifyingglass")
.foregroundColor(.gray)
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
.padding(.leading, 8)
if !viewModel.text.isEmpty {
Button(action: {
self.viewModel.text = ""
}) {
Image(systemName: "multiply.circle.fill")
.foregroundColor(.gray)
.padding(.trailing, 8)
}
}
}
)
.padding(.horizontal, 10)
}
if(viewModel.users.isEmpty){
EmptyInfo(emoji:"👥", title: "Vous navez pas encore damis", explain: "Ajoutez les depuis cet écran").padding(.top, 40)
}
else{
if !viewModel.text.isEmpty {
Button(action: {
self.viewModel.text = ""
}) {
Image(systemName: "multiply.circle.fill")
.foregroundColor(.gray)
.padding(.trailing, 8)
}
ForEach(viewModel.users, id: \.self) { friend in
Friend(user: friend, isRequest: false, viewModel: viewModel)
}
}
)
.padding(.horizontal, 10)
}
if(viewModel.users.isEmpty){
EmptyInfo(emoji:"👥", title: "Vous navez pas encore damis", explain: "Ajoutez les depuis cet écran").padding(.top, 40)
}
else{
ScrollView(showsIndicators: false){
ForEach(viewModel.users, id: \.self) { friend in
Friend(user: friend, viewModel: viewModel)
}
Spacer()
}
.refreshable {
viewModel.getItems()
}
.padding(.top, 50)
.tag(0)
VStack(alignment: .center, spacing: 0) {
if(viewModel.requests.isEmpty){
EmptyInfo(emoji:"📬", title: "Aucune demande d'amis en attente", explain: "").padding(.top, 40)
}
else{
ScrollView(showsIndicators: false){
ForEach(viewModel.requests, id: \.self) { request in
Friend(user: request, isRequest: true, viewModel: viewModel)
}
}
.refreshable {
viewModel.getRequests()
}
.padding(.top, 25)
}
Spacer()
}
.padding(.top, 25)
.padding(.top, 50)
.tag(1)
}
Spacer()
.overlay(
HStack {
Button(action: {
selectedTab = 0
}) {
Text("friends_title")
.font(.system(size: 16))
.padding()
.fontWeight(selectedTab == 0 ? .bold : .semibold)
.foregroundColor(selectedTab == 0 ? AllInColors.primaryTextColor : .gray)
.offset(y: 0)
}
Button(action: {
selectedTab = 1
}) {
Text(String(localized: "friends_request") + (viewModel.requests.isEmpty ? "" : "(\(viewModel.requests.count.description))"))
.font(.system(size: 16))
.padding()
.fontWeight(selectedTab == 1 ? .bold : .semibold)
.foregroundColor(selectedTab == 1 ? AllInColors.primaryTextColor : .gray)
.offset(y: 0)
}
}
, alignment: .top)
.tabViewStyle(PageTabViewStyle())
}
.edgesIgnoringSafeArea(.bottom)
.background(AllInColors.backgroundColor)

@ -142,6 +142,33 @@ public struct UserApiManager: UserDataManager {
}.resume()
}
public func getRequests(completion: @escaping ([User]) -> Void) {
let url = URL(string: allInApi + "friends/requests")!
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
var users: [User] = []
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
print ("ALLIN : get friends")
do {
if let httpResponse = response as? HTTPURLResponse, let jsonArray = try JSONSerialization.jsonObject(with: data, options: []) as? [[String: Any]] {
print(jsonArray)
users = try JSONDecoder().decode([User].self, from: JSONSerialization.data(withJSONObject: jsonArray))
print(httpResponse.statusCode)
completion(users)
}
} catch {
print("Error parsing JSON: \(error)")
}
}
}.resume()
}
public func getUsers(withName name: String, completion: @escaping ([User]) -> Void) {
let url = URL(string: allInApi + "friends/search/" + name)!

@ -58,6 +58,12 @@ public struct Manager {
}
}
public func getRequests(completion: @escaping ([User]) -> Void) {
userDataManager.getRequests() { users in
completion(users)
}
}
public func getUsers(withName name: String, completion: @escaping ([User]) -> Void) {
userDataManager.getUsers(withName: name) { users in
completion(users)

@ -14,6 +14,7 @@ public protocol UserDataManager {
func addFriend(username: String, completion : @escaping (Int)-> ())
func removeFriend(username: String, completion : @escaping (Int)-> ())
func getFriends(completion: @escaping ([User]) -> Void)
func getRequests(completion: @escaping ([User]) -> Void)
func getUsers(withName name: String, completion: @escaping ([User]) -> Void)
func getGifts(completion : @escaping (Int, Int)-> ())
func getOldBets(withIndex index: Int, withCount count: Int, completion: @escaping ([Bet]) -> Void)

Loading…
Cancel
Save