Proyectos de Subversion Iphone Microlearning - Inconcert

Rev

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