Proyectos de Subversion Iphone Microlearning - Inconcert

Rev

Rev 17 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
//
2
//  CommentAndRatingView.swift
3
//  twogetskills
4
//
5
//  Created by Efrain Yanez Recanatini on 7/28/22.
6
//
7
 
8
import SwiftUI
9
import AudioToolbox
10
import Network
11
import Alamofire
12
import SwiftyJSON
13
import TTGSnackbar
14
 
15
 
16
struct CommentAndRatingView: View {
17
    @EnvironmentObject private var networkMonitor : NetworkMonitor
18
    @EnvironmentObject private var appNavigation : AppNavigation
19
 
20
    @State private var capsuleTitle : String = ""
21
 
22
 
23
    @ObservedObject var commentsViewModel  : CommentAndRatingCommentsViewModel = CommentAndRatingCommentsViewModel()
24
 
25
    @ObservedObject var  capsuleViewModel : CommentAndRatingCapsuleViewModel = CommentAndRatingCapsuleViewModel()
26
 
27
    @State var refreshListComment : Bool = true
28
 
29
 
30
    @State var rating : Double = 5.0
31
    @State var comment : String = "" {
32
        didSet {
33
            if comment.count > 128 {
34
                comment =  String(comment.prefix(128))
35
                AudioServicesPlayAlertSoundWithCompletion(SystemSoundID(kSystemSoundID_Vibrate)) { return }
36
            }
37
        }
38
    }
39
 
40
    @State private var selectedType: CommentAndRatingPickerType = .introduction
41
 
42
    @State private var presentAlert : Bool = false
43
    @State private var titleAlert : String = ""
44
    @State private var messageAlert : String = ""
45
 
46
    @State private var showProgressView : Bool = false
47
 
21 efrain 48
    private var appData = Environment(\.appData).wrappedValue
1 efrain 49
    var body: some View {
50
 
51
 
52
 
53
        VStack(spacing: 0)
54
        {
55
            HStack {
56
                Button(action: {
57
                    withAnimation {
58
                        appNavigation.subpageActive = .mycapsules
59
                    }
60
                }, label: {
61
 
62
 
63
                    Image(systemName: "chevron.backward")
64
                    .frame(width: 32, height: 32, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
65
                    .aspectRatio(contentMode: .fit)
66
                    .foregroundColor(networkMonitor.status == .disconnected ? Color("color_network_disconnected_foreground") : Color("color_app_bar_foreground"))
67
                })
68
                .padding(.leading, 16)
69
 
70
                Text(networkMonitor.status == .disconnected ? Config.LANG_ERROR_NETWORK_MESSAGE_SHORT :  capsuleTitle)
71
                .font(Font.custom(Config.FONT_NAME_REGULAR, size: Config.FONT_SIZE_APP_BAR_HEAD1 ))
72
                    .foregroundColor(networkMonitor.status == .disconnected ? Color("color_network_disconnected_foreground") : Color("color_app_bar_foreground"))
73
                    .padding(.leading, 4)
74
 
75
                Spacer()
76
            }
77
            .edgesIgnoringSafeArea(.top)
78
            .frame(height: 50)
79
            .background(networkMonitor.status == .disconnected ? Color("color_network_disconnected_background") : Color("color_app_bar_background"))
80
 
81
 
82
            Divider().background(networkMonitor.status == .disconnected ? Color("color_network_disconnected_background") : Color("color_app_bar_background"))
83
 
84
 
85
 
86
            CommentAndRatingImageView(capsuleModel: self.capsuleViewModel.capsule)
87
 
88
            CommentAndRatingPickerView(capsuleModel: self.capsuleViewModel.capsule, selectedType: self.$selectedType).frame(height: 48)
89
 
90
             switch self.selectedType
91
             {
92
                case .introduction :
93
                    CommentAndRatingIntroductionView(capsuleModel:  self.capsuleViewModel.capsule).padding(5)
94
 
95
                case .comments :
96
                    if self.commentsViewModel.comments.count == 0 {
97
                        CommentAndRatingCommentListEmptyView()
98
                    } else {
99
 
100
                        ScrollView {
101
                            LazyVStack  {
102
                                //ForEach(0..<self.comments.count) { index in
103
 
104
                                ForEach(self.commentsViewModel.comments) { commentItem in
105
                                    CommentAndRatingCommentListItemView(comment: commentItem) {
106
                                        deleteComment(id: commentItem.id, linkDelete: commentItem.link_delete  )
107
 
108
                                    }
109
                                }
110
 
111
                            }
112
                        }
113
                    }
114
 
115
 
116
                   // CommentAndRatingCommentListView(comments: self.commentsViewModel.comments, showProgressView: self.$showProgressView).border(Color.blue, width: 1)
117
 
118
                default :
119
                    CommentAndRatingPostCommentView(
120
                        capsuleModel: self.capsuleViewModel.capsule, comment: self.$comment, rating: self.$rating) {
121
                        sendPostComment()
122
                    }
123
 
124
            }
125
 
126
            Spacer()
17 efrain 127
 
128
            Button(action: {
129
 
130
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
131
                    appData.topicUuidActive = self.capsuleViewModel.capsule.topicUuid
132
                    appData.capsuleUuidActive = self.capsuleViewModel.capsule.uuid
133
                    appData.slideUuidActive = ""
134
                    appData.save()
135
 
136
                    appNavigation.subPageSource = .mycapsules
137
 
138
                    withAnimation {
139
                        appNavigation.subpageActive = .slides
140
                    }
141
 
142
                    }
143
 
144
            }, label: {
145
                Text(Config.LANG_COMMON_NEXT)
146
                 .font(Font.custom(Config.FONT_NAME_REGULAR, size: 16))
147
                 .frame(width: UIScreen.main.bounds.width - 32, height: 35)
148
 
149
                    .foregroundColor(Color("color_button_dark_foreground"))
150
                    .background(Color("color_button_dark_background"))
151
                    .border(Color( "color_button_dark_border"), width: Config.BUTTON_BORDER_SIZE)
152
                    .cornerRadius(Config.BUTTON_BORDER_RADIUS)
153
 
154
            })
155
            .padding(.top, 16)
156
            .padding(.leading, 16)
157
            .padding(.trailing, 16)
1 efrain 158
        }
159
        .background(Color("color_picker_background"))
160
        .onAppear {
161
 
162
            self.capsuleViewModel.fetch(capsuleUuid: appData.capsuleUuidActive, userUuid: appData.userUuid)
163
 
164
            if self.capsuleViewModel.capsule.name.count > Constants.APP_BAR_TITLE_MAX_LENGTH {
165
                self.capsuleTitle = String(Array(self.capsuleViewModel.capsule.name)[0...Constants.APP_BAR_TITLE_MAX_LENGTH]) + "..."
166
            } else {
167
                self.capsuleTitle = self.capsuleViewModel.capsule.name
168
            }
169
 
170
            self.reloadComments()
171
 
172
 
173
        } .alert(isPresented: $presentAlert) {
174
            Alert(
175
                title: Text(self.titleAlert),
176
                message: Text(self.messageAlert),
177
                dismissButton: .default(Text(Config.LANG_COMMON_OK))
178
            )
179
        }
180
    }
181
 
182
    func reloadComments()
183
    {
184
        self.commentsViewModel.comments.removeAll()
185
 
186
        if !self.capsuleViewModel.capsule.linkComments.isEmpty && networkMonitor.status == .connected {
187
 
188
            let headerSecurity : HeaderSecurity = HeaderSecurity()
189
 
190
            let headers: HTTPHeaders = [
191
                .init(name: Constants.HTTP_HEADER_SECURITY_TOKEN, value: appData.deviceUuid),
192
                .init(name: Constants.HTTP_HEADER_SECURITY_SECRET, value: headerSecurity.secret),
193
                .init(name: Constants.HTTP_HEADER_SECURITY_CREATED, value: String(headerSecurity.created)),
194
                .init(name: Constants.HTTP_HEADER_SECURITY_RAND, value: String(headerSecurity.rand)),
195
                .accept(Constants.HTTP_HEADER_ACCEPT)
196
            ]
197
 
198
            //print("URL Comments: \(self.capsuleViewModel.capsule.linkComments)")
199
 
200
            commentsViewModel.comments.removeAll()
201
 
202
            AF.request(self.capsuleViewModel.capsule.linkComments, method: .get, headers: headers).responseJSON{(response) in
203
                    self.showProgressView = false
204
                    switch response.result {
205
                        case .success:
206
                            let json = try? JSON(data: response.data!)
207
 
208
                           // print("json : \(json)")
209
 
210
                            if json?["success"] ?? "" != false {
211
 
212
                                if json?["data"]["capsule"] != nil  {
213
                                    let sTotalComments = json?["data"]["capsule"]["total_comments"].string ?? ""
214
 
215
                                    let sTotalRating = json?["data"]["capsule"]["total_rating"].string ?? ""
216
 
217
                                    capsuleViewModel.capsule.totalComments = Int(sTotalComments) ?? 0
218
                                    capsuleViewModel.capsule.totalRating = Decimal(Double(sTotalRating) ?? 0)
219
 
17 efrain 220
                                    let capsuleDao = CapsuleDao()
1 efrain 221
                                    capsuleDao.update(capsule: capsuleViewModel.capsule)
222
                                }
223
 
224
                                if json?["data"]["comments"] != nil  {
225
                                    var newComment : CommentAndRatingComment
226
                                    for jcomment in json!["data"]["comments"]
227
                                    {
228
                                        newComment = CommentAndRatingComment()
229
                                        newComment.date = jcomment.1["date"].string ?? ""
230
                                        newComment.rating = Decimal(Double(jcomment.1["rating"].string ??  "") ?? 0)
231
                                        newComment.fullname = jcomment.1["fullname"].string ?? ""
232
                                        newComment.comment = jcomment.1["comment"].string ?? ""
233
                                        newComment.image = jcomment.1["image"].string ?? ""
234
                                        newComment.link_delete = jcomment.1["link_delete"].string ?? ""
235
                                        let sDate = jcomment.1["date"].string ?? ""
236
 
237
                                        let formatterService = DateFormatter()
238
                                        formatterService.dateFormat = Constants.FORMAT_DATETIME_SERVICE
239
                                        if let date = formatterService.date(from: sDate) {
240
 
241
                                            let dateFormatterUser = DateFormatter()
242
                                            dateFormatterUser.dateFormat = Constants.FORMAT_DATE_TIME_24
243
                                            newComment.date =  dateFormatterUser.string(from: date)
244
 
245
 
246
                                        }
247
 
248
 
249
 
250
 
251
                                        commentsViewModel.comments.append(newComment)
252
                                    }
253
                                }
254
 
255
 
256
 
257
                            } else {
258
                                let message = json?["data"].string ?? ""
259
                                if !message.isEmpty {
260
                                    self.titleAlert = Config.LANG_ERROR_GENERIC_TITLE
261
                                    self.messageAlert = message
262
                                    self.presentAlert = true
263
                                }
264
                            }
265
 
266
                           return
267
 
268
                        case .failure :
269
                            self.titleAlert = Config.LANG_ERROR_COMMUNICATION_TITLE
270
                            self.messageAlert = Config.LANG_ERROR_COMMUNICATION_MESSAGE
271
                            self.presentAlert = true
272
 
273
                            return
274
                    }
275
                }
276
 
277
        }
278
 
279
 
280
    }
281
 
282
    func sendPostComment() {
283
 
284
        let now = Date()
285
        let dateFormatter = DateFormatter()
286
        dateFormatter.dateFormat = Constants.FORMAT_DATETIME_SERVICE
287
        let dateOn = dateFormatter.string(from: now)
288
 
289
        showProgressView = true
290
        let parameters = [
291
            Constants.POST_COMMENT_FIELD_COMMENT: comment,
292
            Constants.POST_COMMENT_FIELD_RATING: "\(Int(rating))",
293
            Constants.POST_COMMENT_FIELD_ADDED_ON: dateOn
294
        ]
295
 
296
        let headerSecurity : HeaderSecurity = HeaderSecurity()
297
 
298
        let headers: HTTPHeaders = [
299
            .init(name: Constants.HTTP_HEADER_SECURITY_TOKEN, value: appData.deviceUuid),
300
            .init(name: Constants.HTTP_HEADER_SECURITY_SECRET, value: headerSecurity.secret),
301
            .init(name: Constants.HTTP_HEADER_SECURITY_CREATED, value: String(headerSecurity.created)),
302
            .init(name: Constants.HTTP_HEADER_SECURITY_RAND, value: String(headerSecurity.rand)),
303
            .accept(Constants.HTTP_HEADER_ACCEPT)
304
        ]
305
 
306
       // print("URL POST COMMENT : \(capsuleViewModel.capsule.linkComments)")
307
 
308
        self.showProgressView = true
309
        AF.request(capsuleViewModel.capsule.linkCommentAdd, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON{(response) in
310
            self.showProgressView = false
311
 
312
            switch response.result {
313
                case .success:
314
 
315
                    let json = try? JSON(data: response.data!)
316
 
317
                    print("json : \(json)")
318
 
319
                    if json?["success"] ?? "" != false {
320
 
321
 
322
                        if json?["data"]["comment"] != nil  {
323
 
324
                            let now = Date()
325
                            let dateFormatter = DateFormatter()
326
                            dateFormatter.dateFormat = Constants.FORMAT_DATETIME_SERVICE
327
                            let dateOn = dateFormatter.string(from: now)
328
 
329
                            let link_delete =  json?["data"]["comment"]["link_delete"].string ?? ""
330
 
331
 
332
                            var newComment = CommentAndRatingComment()
333
                            newComment.date = dateOn
334
                            newComment.image = appData.userImage
335
                            newComment.fullname = "\(appData.userFirstname) \(appData.userLastname)"
336
                            newComment.rating = Decimal(rating)
337
                            newComment.comment = comment
338
                            newComment.link_delete = link_delete
339
 
340
                            commentsViewModel.prepend(newComment: newComment)
341
 
342
                            self.comment = ""
343
                            self.rating = 5
344
                            self.selectedType = .comments
345
                         }
346
 
347
 
348
                        if json?["data"]["capsule"] != nil  {
349
                            let sTotalComments = json?["data"]["capsule"]["total_comments"].string ?? ""
350
 
351
                            let sTotalRating = json?["data"]["capsule"]["total_rating"].string ?? ""
352
 
353
                            capsuleViewModel.capsule.totalComments = Int(sTotalComments) ?? 0
354
                            capsuleViewModel.capsule.totalRating = Decimal(Double(sTotalRating) ?? 0)
355
 
17 efrain 356
                            let capsuleDao = CapsuleDao()
1 efrain 357
                            capsuleDao.update(capsule: capsuleViewModel.capsule)
358
                        }
359
 
360
 
361
 
362
                        if json?["data"]["message"] != nil  {
363
                            let snackbar = TTGSnackbar(message: json?["data"]["message"].string ?? "", duration: .long)
364
                            snackbar.show()
365
 
366
                        }
367
 
368
 
369
 
370
                    } else {
371
                        let message = json?["data"].string ?? ""
372
                        if !message.isEmpty {
373
                            self.titleAlert = Config.LANG_ERROR_GENERIC_TITLE
374
                            self.messageAlert = message
375
                            self.presentAlert = true
376
                        }
377
                    }
378
 
379
                   return
380
 
381
                case .failure :
382
                    self.titleAlert = Config.LANG_ERROR_COMMUNICATION_TITLE
383
                    self.messageAlert = Config.LANG_ERROR_COMMUNICATION_MESSAGE
384
                    self.presentAlert = true
385
 
386
                    return
387
            }
388
        }
389
 
390
 
391
    }
392
 
393
    func deleteComment(id : String, linkDelete : String) {
394
 
395
        showProgressView = true
396
 
397
        let headerSecurity : HeaderSecurity = HeaderSecurity()
398
 
399
        let headers: HTTPHeaders = [
400
            .init(name: Constants.HTTP_HEADER_SECURITY_TOKEN, value: appData.deviceUuid),
401
            .init(name: Constants.HTTP_HEADER_SECURITY_SECRET, value: headerSecurity.secret),
402
            .init(name: Constants.HTTP_HEADER_SECURITY_CREATED, value: String(headerSecurity.created)),
403
            .init(name: Constants.HTTP_HEADER_SECURITY_RAND, value: String(headerSecurity.rand)),
404
            .accept(Constants.HTTP_HEADER_ACCEPT)
405
        ]
406
 
407
        self.showProgressView = true
408
        AF.request(linkDelete, method: .post, encoding: URLEncoding.default, headers: headers).responseJSON{(response) in
409
            self.showProgressView = false
410
 
411
            switch response.result {
412
                case .success:
413
 
414
                    let json = try? JSON(data: response.data!)
415
 
416
                   // print("json : \(json)")
417
 
418
                    if json?["success"] ?? "" != false {
419
 
420
 
421
 
422
 
423
 
424
                        if json?["data"]["capsule"] != nil  {
425
                            let sTotalComments = json?["data"]["capsule"]["total_comments"].string ?? ""
426
 
427
                            let sTotalRating = json?["data"]["capsule"]["total_rating"].string ?? ""
428
 
429
                            capsuleViewModel.capsule.totalComments = Int(sTotalComments) ?? 0
430
                            capsuleViewModel.capsule.totalRating = Decimal(Double(sTotalRating) ?? 0)
431
 
17 efrain 432
                            let capsuleDao = CapsuleDao()
1 efrain 433
                            capsuleDao.update(capsule: capsuleViewModel.capsule)
434
                        }
435
 
436
 
437
 
438
                        if json?["data"]["message"] != nil  {
439
                            let snackbar = TTGSnackbar(message: json?["data"]["message"].string ?? "", duration: .long)
440
                            snackbar.show()
441
 
442
                        }
443
 
444
                        self.commentsViewModel.removeItem(id: id)
445
 
446
 
447
 
448
                    } else {
449
                        let message = json?["data"].string ?? ""
450
                        if !message.isEmpty {
451
                            self.titleAlert = Config.LANG_ERROR_GENERIC_TITLE
452
                            self.messageAlert = message
453
                            self.presentAlert = true
454
                        }
455
                    }
456
 
457
                   return
458
 
459
                case .failure :
460
                    self.titleAlert = Config.LANG_ERROR_COMMUNICATION_TITLE
461
                    self.messageAlert = Config.LANG_ERROR_COMMUNICATION_MESSAGE
462
                    self.presentAlert = true
463
 
464
                    return
465
            }
466
        }
467
 
468
 
469
    }
470
}
471
 
472
struct CommentAndRatingView_Previews: PreviewProvider {
473
    static var previews: some View {
474
        CommentAndRatingView()
475
    }
476
}
477
 
478