Skip to content

Commit

Permalink
Merge branch 'main' into jwt-auth
Browse files Browse the repository at this point in the history
  • Loading branch information
dhruvna1k committed Mar 11, 2024
2 parents b4bb554 + 257bbcd commit 56427cf
Show file tree
Hide file tree
Showing 9 changed files with 617 additions and 175 deletions.
4 changes: 0 additions & 4 deletions Prisma.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,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 @@ -156,7 +155,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 @@ -416,7 +414,6 @@
isa = PBXGroup;
children = (
AC69903D2B6C5A2F00D92970 /* PrivacyModule.swift */,
AC69903F2B6C627100D92970 /* ToggleTestView.swift */,
D8F136C42B85CEED000BA7AE /* DeleteDataView.swift */,
D8027E902B90655700BB9466 /* ManageDataView.swift */,
);
Expand Down Expand Up @@ -704,7 +701,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 @@ struct DeleteDataView: View {
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] = []
// 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] = []

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

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
}
.navigationTitle(privacyModule.identifierInfo[categoryIdentifier]?.uiString ?? "Identifier Title Not Found")
.onAppear {
Task {
timeArrayStatic = await standard.fetchTop10RecentTimeStamps(selectedTypeIdentifier: categoryIdentifier)
}
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)
}
}
}

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

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)
}
))
}
}

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
)
}
switchHiddenInBackend(identifier: categoryIdentifier, timestamps: customRangeTimestamps, alwaysHide: true)
}
.padding(.top, -40)
.navigationBarItems(trailing: EditButton())
// .frame(maxWidth: .infinity) // Make the button take full width
}
}
.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
}
}

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)
}
}

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

func switchHiddenInBackend(identifier: String, timestamps: [String], alwaysHide: Bool) {
for timestamp in timestamps {
Task {
await standard.addDeleteFlag(selectedTypeIdentifier: identifier, timestamp: timestamp)
await standard.switchHideFlag(selectedTypeIdentifier: identifier, timestamp: timestamp, alwaysHide: alwaysHide)
}
}
}
}


#Preview {
DeleteDataView(categoryIdentifier: "Example Preview: DeleteDataView")
struct DeleteDataView_Previews: PreviewProvider {
static var previews: some View {
DeleteDataView(categoryIdentifier: "Example Preview: DeleteDataView")
}
}
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)
}
}
}
}
}
.navigationTitle("Manage Data")
}
.onReceive(privacyModule.identifierInfoPublisher) { _ in
self.privacyModule.objectWillChange.send()
}
}
}

Expand Down
Loading

0 comments on commit 56427cf

Please sign in to comment.