-
Notifications
You must be signed in to change notification settings - Fork 0
/
RecordListViewController.swift
195 lines (151 loc) · 7.06 KB
/
RecordListViewController.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
import UIKit
import FirebaseFirestore
import FirebaseAuth
import AVFoundation
class RecordListViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var table: UITableView!
var data: [Record] = []
var audioPlayer: AVAudioPlayer?
override func viewDidLoad() {
super.viewDidLoad()
table.dataSource = self
table.delegate = self
// Fetch recordings from Firestore
fetchRecordings()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let record = data[indexPath.row]
let cell = table.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomeTableViewCell
cell.label.text = record.name
cell.iconImageView.image = UIImage(named: record.imageName)
// Add tap gesture recognizer to the play button
let playTapGesture = UITapGestureRecognizer(target: self, action: #selector(playRecording(_:)))
cell.iconImageView.isUserInteractionEnabled = true
cell.iconImageView.tag = indexPath.row // Store the index for reference
cell.iconImageView.addGestureRecognizer(playTapGesture)
// Add tap gesture recognizer to the label (for showing delete popup)
let labelTapGesture = UITapGestureRecognizer(target: self, action: #selector(showDeletePopup(_:)))
cell.label.isUserInteractionEnabled = true
cell.label.tag = indexPath.row // Store the index for reference
cell.label.addGestureRecognizer(labelTapGesture)
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 80
}
@objc func playRecording(_ sender: UITapGestureRecognizer) {
guard let index = sender.view?.tag else { return }
let record = data[index]
playNotes(record)
}
@objc func showDeletePopup(_ sender: UITapGestureRecognizer) {
guard let index = sender.view?.tag else { return }
let record = data[index]
let alertController = UIAlertController(title: "Manage Recording", message: "What would you like to do with this recording?", preferredStyle: .alert)
// Delete action
let deleteAction = UIAlertAction(title: "Delete", style: .destructive) { [weak self] _ in
self?.deleteRecordFromDatabase(record)
}
// Cancel action
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alertController.addAction(deleteAction)
alertController.addAction(cancelAction)
present(alertController, animated: true, completion: nil)
}
func playNotes(_ record: Record) {
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
for (index, note) in record.notes.enumerated() {
let delay: TimeInterval
if index == 0 {
delay = 0.0 // Play the first note immediately
} else {
delay = record.timeIntervals[index - 1] // Use the previous interval for delay
}
// Sleep for the delay interval
Thread.sleep(forTimeInterval: delay)
// Play the sound on the main thread to ensure UI updates
DispatchQueue.main.async {
self?.playSound(noteName: note)
print("Playing note: \(note) after \(delay) seconds")
}
}
}
}
func playSound(noteName: String) {
if let soundURL = Bundle.main.url(forResource: noteName, withExtension: "wav", subdirectory: "Sounds") {
do {
self.audioPlayer = try AVAudioPlayer(contentsOf: soundURL)
self.audioPlayer?.play()
} catch {
print("Could not load sound file: \(error.localizedDescription)")
}
} else {
print("Sound file not found for note: \(noteName)")
}
}
func deleteRecordFromDatabase(_ record: Record) {
guard let user = Auth.auth().currentUser else {
print("No user is logged in.")
return
}
let db = Firestore.firestore()
let userID = user.uid
// Find the document ID based on the record's name (assuming name is unique)
db.collection("users").document(userID).collection("recordings").whereField("name", isEqualTo: record.name).getDocuments { [weak self] snapshot, error in
if let error = error {
print("Error fetching record to delete: \(error.localizedDescription)")
return
}
guard let document = snapshot?.documents.first else {
print("No matching record found to delete.")
return
}
// Delete the document
document.reference.delete { error in
if let error = error {
print("Error deleting record: \(error.localizedDescription)")
} else {
print("Record deleted successfully.")
// Remove the record from the local array and reload the table view
if let index = self?.data.firstIndex(where: { $0.name == record.name }) {
self?.data.remove(at: index)
self?.table.reloadData()
}
}
}
}
}
func fetchRecordings() {
guard let user = Auth.auth().currentUser else {
print("No user is logged in.")
return
}
let db = Firestore.firestore()
let userID = user.uid
db.collection("users").document(userID).collection("recordings").getDocuments { [weak self] snapshot, error in
if let error = error {
print("Error fetching recordings: \(error.localizedDescription)")
return
}
guard let documents = snapshot?.documents else {
print("No recordings found.")
return
}
self?.data.removeAll()
for document in documents {
let data = document.data()
if let name = data["name"] as? String,
let notes = data["notes"] as? [String],
let timeIntervals = data["timeIntervals"] as? [TimeInterval] {
let record = Record(name: name, notes: notes, timeIntervals: timeIntervals, imageName: "play")
self?.data.append(record)
}
}
// Reload the table view with the fetched data
self?.table.reloadData()
}
}
}