Proyectos de Subversion Iphone Microlearning - Nuevo Interface

Rev

Rev 1 | Rev 11 | 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
8 efrain 10
import Network
11
import Alamofire
12
import SwiftyJSON
13
import TTGSnackbar
1 efrain 14
 
8 efrain 15
 
1 efrain 16
struct CommentAndRatingView: View {
8 efrain 17
    @EnvironmentObject private var networkMonitor : NetworkMonitor
18
    @EnvironmentObject private var appNavigation : AppNavigation
1 efrain 19
 
8 efrain 20
    @State private var capsuleTitle : String = ""
21
 
1 efrain 22
 
8 efrain 23
    @ObservedObject var commentsViewModel  : CommentAndRatingCommentsViewModel = CommentAndRatingCommentsViewModel()
1 efrain 24
 
8 efrain 25
    @ObservedObject var  capsuleViewModel : CommentAndRatingCapsuleViewModel = CommentAndRatingCapsuleViewModel()
1 efrain 26
 
8 efrain 27
    @State var refreshListComment : Bool = true
28
 
29
 
30
    @State var rating : Double = 5.0
31
    @State var comment : String = "" {
1 efrain 32
        didSet {
33
            if comment.count > 128 {
34
                comment =  String(comment.prefix(128))
35
                AudioServicesPlayAlertSoundWithCompletion(SystemSoundID(kSystemSoundID_Vibrate)) { return }
36
            }
37
        }
38
    }
39
 
8 efrain 40
 
1 efrain 41
 
8 efrain 42
 
1 efrain 43
    @State private var selectedType: CommentAndRatingPickerType = .introduction
44
 
8 efrain 45
    @State private var presentAlert : Bool = false
46
    @State private var titleAlert : String = ""
47
    @State private var messageAlert : String = ""
48
 
49
    @State private var showProgressView : Bool = false
50
 
51
    private let appData : AppData = AppData.sharedInstance
52
 
53
 
54
 
1 efrain 55
    var body: some View {
56
 
57
 
58
 
59
        VStack(spacing: 0)
60
        {
61
            HStack {
8 efrain 62
                Button(action: {
63
                    withAnimation {
64
                        appNavigation.subpageActive = .mycapsules
65
                    }
66
                }, label: {
67
 
68
 
69
                    Image(systemName: "chevron.backward")
70
                    .frame(width: 32, height: 32, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
71
                    .aspectRatio(contentMode: .fit)
72
                    .foregroundColor(networkMonitor.status == .disconnected ? Color("color_network_disconnected_foreground") : Color("color_app_bar_foreground"))
73
                })
1 efrain 74
                .padding(.leading, 16)
75
 
8 efrain 76
                Text(networkMonitor.status == .disconnected ? Config.LANG_ERROR_NETWORK_MESSAGE_SHORT :  capsuleTitle)
1 efrain 77
                .font(Font.custom(Config.FONT_NAME_REGULAR, size: Config.FONT_SIZE_APP_BAR_HEAD1 ))
8 efrain 78
                    .foregroundColor(networkMonitor.status == .disconnected ? Color("color_network_disconnected_foreground") : Color("color_app_bar_foreground"))
79
                    .padding(.leading, 4)
1 efrain 80
 
81
                Spacer()
82
            }
83
            .edgesIgnoringSafeArea(.top)
84
            .frame(height: 50)
8 efrain 85
            .background(networkMonitor.status == .disconnected ? Color("color_network_disconnected_background") : Color("color_app_bar_background"))
86
 
87
 
88
            Divider().background(networkMonitor.status == .disconnected ? Color("color_network_disconnected_background") : Color("color_app_bar_background"))
89
 
1 efrain 90
 
91
 
8 efrain 92
            CommentAndRatingImageView(capsuleModel: self.capsuleViewModel.capsule)
1 efrain 93
 
8 efrain 94
            CommentAndRatingPickerView(capsuleModel: self.capsuleViewModel.capsule, selectedType: self.$selectedType).frame(height: 48)
1 efrain 95
 
96
             switch self.selectedType
97
             {
98
                case .introduction :
8 efrain 99
                    CommentAndRatingIntroductionView(capsuleModel:  self.capsuleViewModel.capsule).padding(5)
1 efrain 100
 
101
                case .comments :
8 efrain 102
                    CommentAndRatingCommentListView(comments: self.commentsViewModel.comments, showProgressView: self.$showProgressView).border(Color.blue, width: 1)
1 efrain 103
 
104
                default :
8 efrain 105
                    CommentAndRatingPostCommentView(
106
                        capsuleModel: self.capsuleViewModel.capsule, comment: self.$comment, rating: self.$rating)
107
 
1 efrain 108
            }
109
 
110
            Spacer()
8 efrain 111
        }
112
        .background(Color("color_picker_background"))
113
        .onAppear {
114
 
115
            self.capsuleViewModel.fetch(capsuleUuid: appData.capsuleUuidActive, userUuid: appData.userUuid)
116
 
117
            if self.capsuleViewModel.capsule.name.count > Constants.APP_BAR_TITLE_MAX_LENGTH {
118
                self.capsuleTitle = String(Array(self.capsuleViewModel.capsule.name)[0...Constants.APP_BAR_TITLE_MAX_LENGTH]) + "..."
119
            } else {
120
                self.capsuleTitle = self.capsuleViewModel.capsule.name
121
            }
122
 
123
            self.reloadComments()
124
 
125
 
126
        } .alert(isPresented: $presentAlert) {
127
            Alert(
128
                title: Text(self.titleAlert),
129
                message: Text(self.messageAlert),
130
                dismissButton: .default(Text(Config.LANG_COMMON_OK))
131
            )
132
        }
133
      .onReceive(NotificationCenter.default.publisher(for: Constants.NOTIFICATION_NAME_COMMAND_POST_COMMENT))
134
        { data in
135
 
136
 
137
            sendPostComment()
138
        }
1 efrain 139
    }
8 efrain 140
 
141
    func reloadComments()
142
    {
143
        self.commentsViewModel.comments.removeAll()
144
 
145
        if !self.capsuleViewModel.capsule.linkComments.isEmpty && networkMonitor.status == .connected {
146
 
147
            let headerSecurity : HeaderSecurity = HeaderSecurity()
148
 
149
            let headers: HTTPHeaders = [
150
                .init(name: Constants.HTTP_HEADER_SECURITY_TOKEN, value: appData.deviceUuid),
151
                .init(name: Constants.HTTP_HEADER_SECURITY_SECRET, value: headerSecurity.secret),
152
                .init(name: Constants.HTTP_HEADER_SECURITY_CREATED, value: String(headerSecurity.created)),
153
                .init(name: Constants.HTTP_HEADER_SECURITY_RAND, value: String(headerSecurity.rand)),
154
                .accept(Constants.HTTP_HEADER_ACCEPT)
155
            ]
156
 
157
            print("URL Comments: \(self.capsuleViewModel.capsule.linkComments)")
158
 
159
            AF.request(self.capsuleViewModel.capsule.linkComments, method: .get, headers: headers).responseJSON{(response) in
160
                    self.showProgressView = false
161
                    switch response.result {
162
                        case .success:
163
                            let json = try? JSON(data: response.data!)
164
 
165
                            print("json : \(json)")
166
 
167
                            if json?["success"] ?? "" != false {
168
                                let dataService = DataService()
169
 
170
                                dataService.syncFromServer(json : json)
171
                            } else {
172
                                let message = json?["data"].string ?? ""
173
                                if !message.isEmpty {
174
                                    self.titleAlert = Config.LANG_ERROR_GENERIC_TITLE
175
                                    self.messageAlert = message
176
                                    self.presentAlert = true
177
                                }
178
                            }
179
 
180
                           return
181
 
182
                        case .failure :
183
                            self.titleAlert = Config.LANG_ERROR_COMMUNICATION_TITLE
184
                            self.messageAlert = Config.LANG_ERROR_COMMUNICATION_MESSAGE
185
                            self.presentAlert = true
186
 
187
                            return
188
                    }
189
                }
190
 
191
        }
192
 
193
 
194
    }
195
 
196
    func sendPostComment() {
197
 
198
 
199
        showProgressView = true
200
        let parameters = [
201
            Constants.POST_COMMENT_FIELD_COMMENT: "\(comment)",
202
            Constants.POST_COMMENT_FIELD_RATING: "\(rating)",
203
        ]
204
 
205
        let headerSecurity : HeaderSecurity = HeaderSecurity()
206
 
207
        let headers: HTTPHeaders = [
208
            .init(name: Constants.HTTP_HEADER_SECURITY_TOKEN, value: appData.deviceUuid),
209
            .init(name: Constants.HTTP_HEADER_SECURITY_SECRET, value: headerSecurity.secret),
210
            .init(name: Constants.HTTP_HEADER_SECURITY_CREATED, value: String(headerSecurity.created)),
211
            .init(name: Constants.HTTP_HEADER_SECURITY_RAND, value: String(headerSecurity.rand)),
212
            .accept(Constants.HTTP_HEADER_ACCEPT)
213
        ]
214
 
215
        print("URL POST COMMENT : \(capsuleViewModel.capsule.linkComments)")
216
 
217
        self.showProgressView = true
218
        AF.request(capsuleViewModel.capsule.linkComments, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON{(response) in
219
            self.showProgressView = false
220
 
221
            switch response.result {
222
                case .success:
223
                    let json = try? JSON(data: response.data!)
224
 
225
                    print("json : \(json)")
226
 
227
                    if json?["success"] ?? "" != false {
228
 
229
 
230
                        if json?["data"]["comment"] != nil  {
231
 
232
                            let now = Date()
233
                            let dateFormatter = DateFormatter()
234
                            dateFormatter.dateFormat = Constants.FORMAT_DATETIME_SERVICE
235
                            let dateOn = dateFormatter.string(from: now)
236
 
237
                            let link_delete =  json?["data"]["comment"]["comment"].string ?? ""
238
 
239
 
240
 
241
 
242
                            let newComment = CommentAndRatingComment(date: dateOn,
243
                                image: appData.image,
244
                                fullname: "\(appData.firstName) \(appData.lastName)",
245
                                rating: Decimal(rating),
246
                                comment: comment, link_delete:
247
                                    link_delete)
248
 
249
                            commentsViewModel.comments.insert(newComment, at: 0)
250
                         }
251
 
252
 
253
                        if json?["data"]["capsule"] != nil  {
254
                            let sTotalComments = json?["data"]["capsule"]["total_comments"].string ?? ""
255
 
256
                            let sTotalRating = json?["data"]["capsule"]["total_rating"].string ?? ""
257
 
258
                            capsuleViewModel.capsule.totalComments = Int(sTotalComments) ?? 0
259
                            capsuleViewModel.capsule.totalRating = Decimal(Double(sTotalRating) ?? 0)
260
 
261
                            let capsuleDao = CapsuleDao.sharedInstance
262
                            capsuleDao.update(capsule: capsuleViewModel.capsule)
263
                        }
264
 
265
 
266
 
267
                        if json?["data"]["message"] != nil  {
268
                            let snackbar = TTGSnackbar(message: json?["data"]["message"].string ?? "", duration: .short)
269
                            snackbar.show()
270
 
271
                        }
272
 
273
 
274
 
275
                    } else {
276
                        let message = json?["data"].string ?? ""
277
                        if !message.isEmpty {
278
                            self.titleAlert = Config.LANG_ERROR_GENERIC_TITLE
279
                            self.messageAlert = message
280
                            self.presentAlert = true
281
                        }
282
                    }
283
 
284
                   return
285
 
286
                case .failure :
287
                    self.titleAlert = Config.LANG_ERROR_COMMUNICATION_TITLE
288
                    self.messageAlert = Config.LANG_ERROR_COMMUNICATION_MESSAGE
289
                    self.presentAlert = true
290
 
291
                    return
292
            }
293
        }
294
 
295
 
296
    }
1 efrain 297
}
298
 
299
struct CommentAndRatingView_Previews: PreviewProvider {
300
    static var previews: some View {
301
        CommentAndRatingView()
302
    }
303
}
304
 
305