Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Features/readtimestamps: Read timestamps from FireStore; Pause Uploading to FireStore and Hide/Unhide Timestamps #39

Merged
merged 22 commits into from
Mar 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d4952ce
Change deleting data functionality to hiding/unhiding in UI and Fires…
evelyn-hur Mar 7, 2024
b139ecc
Minor changes to DeleteDataView UI
evelyn-hur Mar 7, 2024
f76b40c
Add data type description and hide by custom range date picker
evelyn-hur Mar 7, 2024
0afba4a
Minor Changes: Rename all functions and variables from delete to hide…
evelyn-hur Mar 7, 2024
927c6e3
ManageDataView dependent on PrismaDelegate sample types
carolinentran Mar 7, 2024
5085177
Add fetchTop10RecentTimeStamps function to read in timestamps
evelyn-hur Mar 7, 2024
b177527
Merge branch 'features/readtimestamps' of https://github.com/CS342/20…
evelyn-hur Mar 7, 2024
989ec7a
Quick Fix: Minor Error with accessing uiString
evelyn-hur Mar 7, 2024
ed94b9f
Fixed bug for fetchTop10RecentTimeStamps
evelyn-hur Mar 7, 2024
9539f51
[Work in Progress] Saving toggle update changes to merge main into br…
carolinentran Mar 7, 2024
7889705
Merge branch 'main' into features/readtimestamps
carolinentran Mar 7, 2024
73a433e
Disable/Enable Category Toggle updates dictionary value
carolinentran Mar 8, 2024
a0249c0
Rewrote updateAndSignalOnChange and added description test to localizer
carolinentran Mar 8, 2024
3372b68
Quick Fix: Typo with walking heart rate description
carolinentran Mar 9, 2024
0af679a
Merge branch 'main' into features/readtimestamps
carolinentran Mar 9, 2024
72090de
Change sort by "time.datetime.start" and descending order
carolinentran Mar 10, 2024
b6f40e3
Merge branch 'main' into features/readtimestamps
carolinentran Mar 10, 2024
c61a438
functionality for firestore ignoring false data types
dhruvna1k Mar 10, 2024
7d3fbca
Replaced "time.datetime.start" with "issued" for sorting 10 most rece…
carolinentran Mar 11, 2024
9b44804
Backend for hide by custom range
evelyn-hur Mar 11, 2024
5b7d05e
UI Change: Centered and Divided Hide Button and fixed lint errors
carolinentran Mar 11, 2024
ad275fd
PR Feedback: Reset useFirebaseEmulator = true
carolinentran Mar 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions Prisma.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@
A9DFE8A92ABE551400428242 /* AccountButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9DFE8A82ABE551400428242 /* AccountButton.swift */; };
A9FE7AD02AA39BAB0077B045 /* AccountSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9FE7ACF2AA39BAB0077B045 /* AccountSheet.swift */; };
AC69903E2B6C5A2F00D92970 /* PrivacyModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC69903D2B6C5A2F00D92970 /* PrivacyModule.swift */; };
AC6990402B6C627100D92970 /* ToggleTestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC69903F2B6C627100D92970 /* ToggleTestView.swift */; };
D8027E912B90655700BB9466 /* ManageDataView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8027E902B90655700BB9466 /* ManageDataView.swift */; };
D8F136C52B85CEED000BA7AE /* DeleteDataView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8F136C42B85CEED000BA7AE /* DeleteDataView.swift */; };
E4C766262B72D50500C1DEDA /* WebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4C766252B72D50500C1DEDA /* WebView.swift */; };
Expand Down Expand Up @@ -158,7 +157,6 @@
A9DFE8A82ABE551400428242 /* AccountButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountButton.swift; sourceTree = "<group>"; };
A9FE7ACF2AA39BAB0077B045 /* AccountSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountSheet.swift; sourceTree = "<group>"; };
AC69903D2B6C5A2F00D92970 /* PrivacyModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyModule.swift; sourceTree = "<group>"; };
AC69903F2B6C627100D92970 /* ToggleTestView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleTestView.swift; sourceTree = "<group>"; };
D8027E902B90655700BB9466 /* ManageDataView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManageDataView.swift; sourceTree = "<group>"; };
D8F136C42B85CEED000BA7AE /* DeleteDataView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeleteDataView.swift; sourceTree = "<group>"; };
E4C766252B72D50500C1DEDA /* WebView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -418,7 +416,6 @@
isa = PBXGroup;
children = (
AC69903D2B6C5A2F00D92970 /* PrivacyModule.swift */,
AC69903F2B6C627100D92970 /* ToggleTestView.swift */,
D8F136C42B85CEED000BA7AE /* DeleteDataView.swift */,
D8027E902B90655700BB9466 /* ManageDataView.swift */,
);
Expand Down Expand Up @@ -706,7 +703,6 @@
A9FE7AD02AA39BAB0077B045 /* AccountSheet.swift in Sources */,
D8027E912B90655700BB9466 /* ManageDataView.swift in Sources */,
F8AF6FB42B5F6EDC0011C32D /* PrismaModule.swift in Sources */,
AC6990402B6C627100D92970 /* ToggleTestView.swift in Sources */,
AC69903E2B6C5A2F00D92970 /* PrivacyModule.swift in Sources */,
653A2551283387FE005D4D48 /* Prisma.swift in Sources */,
2FE5DC3629EDD7CA004B9AB4 /* HealthKitPermissions.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"originHash" : "2744d3b6cb9385cb089a3b7f85f47cd50be0044a6d049ff1f93f530ab4329df2",
"pins" : [
{
"identity" : "abseil-cpp-binary",
Expand Down Expand Up @@ -316,5 +317,5 @@
}
}
],
"version" : 2
"version" : 3
}
134 changes: 96 additions & 38 deletions Prisma/PrivacyControls/DeleteDataView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,59 +27,117 @@
var categoryIdentifier: String

// NEXT STEPS: timeArrayStatic will be replaced by timestampsArray which is read in from firestore using the categoryIdentifier and getPath
@State private var timeArrayStatic = ["2023-11-14T20:39:44.467", "2023-11-14T20:41:00.000", "2023-11-14T20:42:00.000"]
@State private var timeArrayStatic: [String] = []

Check warning on line 30 in Prisma/PrivacyControls/DeleteDataView.swift

View check run for this annotation

Codecov / codecov/patch

Prisma/PrivacyControls/DeleteDataView.swift#L30

Added line #L30 was not covered by tests
// var timeArray = getLastTimestamps(quantityType: "stepcount")
@State private var crossedOutTimestamps: [String: Bool] = [:]
@State private var customHideStartDate = Date()
@State private var customHideEndDate = Date()
@State private var customRangeTimestamps: [String] = []

Check warning on line 35 in Prisma/PrivacyControls/DeleteDataView.swift

View check run for this annotation

Codecov / codecov/patch

Prisma/PrivacyControls/DeleteDataView.swift#L32-L35

Added lines #L32 - L35 were not covered by tests

// state variable for the category toggle
@State private var isCategoryToggleOn = false

Check warning on line 38 in Prisma/PrivacyControls/DeleteDataView.swift

View check run for this annotation

Codecov / codecov/patch

Prisma/PrivacyControls/DeleteDataView.swift#L38

Added line #L38 was not covered by tests

var body: some View {
// create a list of all the time stamps for this category
// get rid of spacing once we insert custom time range
VStack(spacing: -400) {
Form {
Section(header: Text("Allow to Read")) {
Toggle(self.privacyModule.identifierUIString[self.categoryIdentifier] ?? "Cannot Find Data Type", isOn: Binding<Bool>(
get: {
// Return the current value or a default value if the key does not exist
self.privacyModule.togglesMap[self.categoryIdentifier] ?? false
},
set: { newValue in
// Update the dictionary with the new value
self.privacyModule.togglesMap[self.categoryIdentifier] = newValue
}
))
}
Form {
descriptionSection
toggleSection
hideByCustomRangeSection
hideByTimeSection
}
carolinentran marked this conversation as resolved.
Show resolved Hide resolved
.navigationTitle(privacyModule.identifierInfo[categoryIdentifier]?.uiString ?? "Identifier Title Not Found")
.onAppear {
Task {
timeArrayStatic = await standard.fetchTop10RecentTimeStamps(selectedTypeIdentifier: categoryIdentifier)

Check warning on line 50 in Prisma/PrivacyControls/DeleteDataView.swift

View check run for this annotation

Codecov / codecov/patch

Prisma/PrivacyControls/DeleteDataView.swift#L41-L50

Added lines #L41 - L50 were not covered by tests
}
NavigationView {
// Toggle corresponding to the proper data to exclude all data of this type
List {
Section(header: Text("Delete by time")) {
ForEach(timeArrayStatic, id: \.self) { timestamp in
Text(timestamp)
}
// on delete, remove it on the UI and set flag in firebase
.onDelete { indices in
let timestampsToDelete = indices.map { timeArrayStatic[$0] }
deleteInBackend(identifier: categoryIdentifier, timestamps: timestampsToDelete)
timeArrayStatic.remove(atOffsets: indices)
}
}
}

Check warning on line 53 in Prisma/PrivacyControls/DeleteDataView.swift

View check run for this annotation

Codecov / codecov/patch

Prisma/PrivacyControls/DeleteDataView.swift#L52-L53

Added lines #L52 - L53 were not covered by tests

var descriptionSection: some View {
Section(header: Text("About")) {
Text(privacyModule.identifierInfo[categoryIdentifier]?.description ?? "Missing Description.")
}
}

Check warning on line 59 in Prisma/PrivacyControls/DeleteDataView.swift

View check run for this annotation

Codecov / codecov/patch

Prisma/PrivacyControls/DeleteDataView.swift#L55-L59

Added lines #L55 - L59 were not covered by tests

var toggleSection: some View {
Section(header: Text("Allow Data Upload")) {
Toggle(privacyModule.identifierInfo[categoryIdentifier]?.uiString ?? "Missing UI Type String ", isOn: Binding<Bool>(
get: {
// get the current enable status for the toggle
// default to a disabled toggle if the value is missing
privacyModule.identifierInfo[categoryIdentifier]?.enabledBool ?? false
},
set: { newValue in
// Update dict with new toggle status, signal to other views about dict change
privacyModule.updateAndSignalOnChange(identifierString: categoryIdentifier, newToggleVal: newValue)
}
))
}
}

Check warning on line 75 in Prisma/PrivacyControls/DeleteDataView.swift

View check run for this annotation

Codecov / codecov/patch

Prisma/PrivacyControls/DeleteDataView.swift#L61-L75

Added lines #L61 - L75 were not covered by tests

var hideByCustomRangeSection: some View {
Section(header: Text("Hide Data by Custom Range")) {
VStack {
DatePicker("Start date", selection: $customHideStartDate, displayedComponents: .date)
DatePicker("End date", selection: $customHideEndDate, displayedComponents: .date)

Divider()

Button("Hide") {
let startDateString = formatDate(customHideStartDate)
let endDateString = formatDate(customHideEndDate)
Task {
customRangeTimestamps = await standard.fetchCustomRangeTimeStamps(
selectedTypeIdentifier: categoryIdentifier,
startDate: startDateString,
endDate: endDateString
)

Check warning on line 93 in Prisma/PrivacyControls/DeleteDataView.swift

View check run for this annotation

Codecov / codecov/patch

Prisma/PrivacyControls/DeleteDataView.swift#L77-L93

Added lines #L77 - L93 were not covered by tests
}
switchHiddenInBackend(identifier: categoryIdentifier, timestamps: customRangeTimestamps, alwaysHide: true)

Check warning on line 95 in Prisma/PrivacyControls/DeleteDataView.swift

View check run for this annotation

Codecov / codecov/patch

Prisma/PrivacyControls/DeleteDataView.swift#L95

Added line #L95 was not covered by tests
}
.padding(.top, -40)
.navigationBarItems(trailing: EditButton())
// .frame(maxWidth: .infinity) // Make the button take full width

Check warning on line 97 in Prisma/PrivacyControls/DeleteDataView.swift

View check run for this annotation

Codecov / codecov/patch

Prisma/PrivacyControls/DeleteDataView.swift#L97

Added line #L97 was not covered by tests
}
}
.navigationTitle(privacyModule.identifierUIString[categoryIdentifier] ?? "Identifier Title Not Found")
}

func deleteInBackend(identifier: String, timestamps: [String]) {
var hideByTimeSection: some View {
Section(header: Text("Hide by Timestamps")) {
timeStampsDisplay
}
}

Check warning on line 106 in Prisma/PrivacyControls/DeleteDataView.swift

View check run for this annotation

Codecov / codecov/patch

Prisma/PrivacyControls/DeleteDataView.swift#L102-L106

Added lines #L102 - L106 were not covered by tests

var timeStampsDisplay: some View {
ForEach(timeArrayStatic, id: \.self) { timestamp in
HStack {
Image(systemName: crossedOutTimestamps[timestamp, default: false] ? "eye.slash" : "eye")
.accessibilityLabel(crossedOutTimestamps[timestamp, default: false] ? "Hide Timestamp" : "Show Timestamp")
.onTapGesture {
switchHiddenInBackend(identifier: categoryIdentifier, timestamps: [timestamp], alwaysHide: false)
crossedOutTimestamps[timestamp]?.toggle() ?? (crossedOutTimestamps[timestamp] = true)
}
Text(timestamp)
}
.foregroundColor(crossedOutTimestamps[timestamp, default: false] ? .gray : .black)
.opacity(crossedOutTimestamps[timestamp, default: false] ? 0.5 : 1.0)
}
}

Check warning on line 122 in Prisma/PrivacyControls/DeleteDataView.swift

View check run for this annotation

Codecov / codecov/patch

Prisma/PrivacyControls/DeleteDataView.swift#L108-L122

Added lines #L108 - L122 were not covered by tests

func formatDate(_ date: Date) -> String {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
return formatter.string(from: date)
}

Check warning on line 128 in Prisma/PrivacyControls/DeleteDataView.swift

View check run for this annotation

Codecov / codecov/patch

Prisma/PrivacyControls/DeleteDataView.swift#L124-L128

Added lines #L124 - L128 were not covered by tests

func switchHiddenInBackend(identifier: String, timestamps: [String], alwaysHide: Bool) {

Check warning on line 130 in Prisma/PrivacyControls/DeleteDataView.swift

View check run for this annotation

Codecov / codecov/patch

Prisma/PrivacyControls/DeleteDataView.swift#L130

Added line #L130 was not covered by tests
for timestamp in timestamps {
Task {
await standard.addDeleteFlag(selectedTypeIdentifier: identifier, timestamp: timestamp)
await standard.switchHideFlag(selectedTypeIdentifier: identifier, timestamp: timestamp, alwaysHide: alwaysHide)

Check warning on line 133 in Prisma/PrivacyControls/DeleteDataView.swift

View check run for this annotation

Codecov / codecov/patch

Prisma/PrivacyControls/DeleteDataView.swift#L133

Added line #L133 was not covered by tests
}
}
}
}


#Preview {
DeleteDataView(categoryIdentifier: "Example Preview: DeleteDataView")
struct DeleteDataView_Previews: PreviewProvider {
static var previews: some View {
DeleteDataView(categoryIdentifier: "Example Preview: DeleteDataView")
}

Check warning on line 142 in Prisma/PrivacyControls/DeleteDataView.swift

View check run for this annotation

Codecov / codecov/patch

Prisma/PrivacyControls/DeleteDataView.swift#L140-L142

Added lines #L140 - L142 were not covered by tests
}
41 changes: 26 additions & 15 deletions Prisma/PrivacyControls/ManageDataView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,40 @@
import SwiftUI

struct ManageDataView: View {
@Environment(PrivacyModule.self) private var privacyModule
@EnvironmentObject var privacyModule: PrivacyModule

var body: some View {
NavigationView {
List(privacyModule.dataCategoryItems, id: \.name) { item in
NavigationLink(destination: DeleteDataView(categoryIdentifier: item.name)) {
HStack(alignment: .center, spacing: 10) {
Image(systemName: item.iconName)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 35, height: 35)
.accessibility(label: Text("accessibility text temp"))
VStack(alignment: .leading, spacing: 4) {
Text(privacyModule.identifierUIString[item.name] ?? "Identifier UI String Not Found")
.font(.headline)
Text(item.enabledStatus)
.font(.subheadline)
.foregroundColor(.gray)
List {
ForEach(privacyModule.sortedSampleIdentifiers, id: \.self) { sampleIdentifier in
NavigationLink(
destination: DeleteDataView(
categoryIdentifier: privacyModule.identifierInfo[sampleIdentifier]?.identifier ?? "missing identifier string"
)
) {
HStack(alignment: .center, spacing: 10) {
Image(systemName: privacyModule.identifierInfo[sampleIdentifier]?.iconName ?? "missing icon name")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 35, height: 35)
.accessibility(label: Text("accessibility text temp"))
VStack(alignment: .leading, spacing: 4) {
Text(privacyModule.identifierInfo[sampleIdentifier]?.uiString ?? "missing ui identifier string")
.font(.headline)
// assume a default value of false if there is a nil value in enabledBool
Text((privacyModule.identifierInfo[sampleIdentifier]?.enabledBool ?? false) ? "Enabled" : "Disabled")
.font(.subheadline)
.foregroundColor(.gray)
}

Check warning on line 43 in Prisma/PrivacyControls/ManageDataView.swift

View check run for this annotation

Codecov / codecov/patch

Prisma/PrivacyControls/ManageDataView.swift#L25-L43

Added lines #L25 - L43 were not covered by tests
}
}
}
}
.navigationTitle("Manage Data")
}
.onReceive(privacyModule.identifierInfoPublisher) { _ in
self.privacyModule.objectWillChange.send()
}

Check warning on line 52 in Prisma/PrivacyControls/ManageDataView.swift

View check run for this annotation

Codecov / codecov/patch

Prisma/PrivacyControls/ManageDataView.swift#L51-L52

Added lines #L51 - L52 were not covered by tests
}
}

Expand Down
Loading
Loading