Skip to content

Commit

Permalink
Merge pull request #61 from BIDMCDigitalPsychiatry/WidgetEnhancements
Browse files Browse the repository at this point in the history
Widget enhancements
  • Loading branch information
jijopulikkottil authored Jul 24, 2024
2 parents 330ba34 + ad3671f commit 1bd051b
Show file tree
Hide file tree
Showing 11 changed files with 215 additions and 84 deletions.
2 changes: 1 addition & 1 deletion CustomNotification/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>408</string>
<string>424</string>
<key>DASHBOARD_URL</key>
<string>$(DASHBOARD_URL)</string>
<key>NSExtension</key>
Expand Down
2 changes: 1 addition & 1 deletion NotificationService/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>408</string>
<string>424</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
Expand Down
2 changes: 1 addition & 1 deletion Shared/EndPoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ enum Endpoint: String {
case sensor = "/participant/%@/sensor"
case getParticipant = "/participant/me"
case activity = "/participant/%@/activity?ignore_binary=true"
case activityEvent = "/participant/%@/activity_event"
case activityEvent = "/participant/%@/activity_event"//?ignore_binary=true

case getLatestDashboard = "/version/get"

Expand Down
86 changes: 60 additions & 26 deletions StreakWidget/StreakWidget.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,24 @@ struct Provider: TimelineProvider {
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {

helper.fetchActivityEvents(participantId: UserDefaults.standard.participantIdShared) { dates in
guard let dates else {
return
}
let reslut = (UserDefaults.standard.streakDataCurrentShared, UserDefaults.standard.streakDataMaxShared)

let entry = SimpleEntry(date: Date(), currentStreak: reslut.0, longestStreak: reslut.1)

//Next fetch happens 15 minutes later
let nextUpdate = Calendar.current.date(
byAdding: DateComponents(hour: 4),
to: Date()
)!
guard dates != nil else {
let entry = SimpleEntry(date: Date(), currentStreak: 0, longestStreak: 0)
let timeline = Timeline(
entries: [entry],
policy: .after(nextUpdate)
)
completion(timeline)
return
}
let reslut = (UserDefaults.standard.streakDataCurrentShared, UserDefaults.standard.streakDataMaxShared)

let entry = SimpleEntry(date: Date(), currentStreak: reslut.0, longestStreak: reslut.1)

let timeline = Timeline(
entries: [entry],
Expand All @@ -54,28 +60,56 @@ struct SimpleEntry: TimelineEntry {
struct StreakWidgetEntryView : View {

var entry: Provider.Entry
@SwiftUI.Environment(\.widgetFamily) var family

@ViewBuilder
var body: some View {
VStack(alignment: .center, spacing: 5) {

Image("logo")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 40)

let daysText1: String = entry.currentStreak == 1 ? "day" : "days"
Text("Current streak: \(entry.currentStreak) \(daysText1)")
.font(.system(size: 12))
.fontWeight(.black)

let daysText: String = entry.longestStreak == 1 ? "day" : "days"
Text("Longest Streak: \(entry.longestStreak) \(daysText)")
.font(.system(size: 12))
.fontWeight(.black)

Text("Way To Go!")
.font(.system(size: 14))
.fontWeight(.bold)

switch family {
case .systemSmall:
VStack(alignment: .center, spacing: 5) {

Image("logo")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 36)

let daysText1: String = entry.currentStreak == 1 ? "day" : "days"
Text("Current streak: \(entry.currentStreak) \(daysText1)")
.font(.system(size: 10))
.fontWeight(.medium)

let daysText: String = entry.longestStreak == 1 ? "day" : "days"
Text("Longest Streak: \(entry.longestStreak) \(daysText)")
.font(.system(size: 10))
.fontWeight(.medium)

Text("Way To Go!")
.font(.system(size: 11))
.fontWeight(.medium)
}
default:
VStack(alignment: .center, spacing: 5) {

Image("logo")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 40)

let daysText1: String = entry.currentStreak == 1 ? "day" : "days"
Text("Current streak: \(entry.currentStreak) \(daysText1)")
.font(.system(size: 14))
.fontWeight(.medium)

let daysText: String = entry.longestStreak == 1 ? "day" : "days"
Text("Longest Streak: \(entry.longestStreak) \(daysText)")
.font(.system(size: 14))
.fontWeight(.medium)

Text("Way To Go!")
.font(.system(size: 15))
.fontWeight(.medium)
}
}
}
}
Expand Down
54 changes: 40 additions & 14 deletions StreakWidgetHelper/StreakWidgetHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,35 +22,54 @@ public class StreakWidgetHelper {
}
}
static var cachedEntry:(Int, Int) = (0, 0)

func longestStreakFor(participantId: String) -> Int {
let dict: [String: Int]? = UserDefaults.standard.object(forKey: "longestActivityStreak") as? [String: Int]
return dict?[participantId] ?? 0
}

func setLongestStreak(streak: Int, participantId: String) {
let dict: [String: Int] = [participantId: streak]
UserDefaults.standard.setValue(dict, forKey: "longestActivityStreak")
}

public func fetchActivityEvents(participantId: String?, completion: (([Date]?) -> Void)?) {

guard let participantId else {
completion?(nil)
return
}
//todo execute once per day

//update server

let task = URLSession.shared.dataTask(with: urlRequest(participantId: participantId)) { [weak self] data, response, error in

let fromDate: Date
if longestStreakFor(participantId: participantId) <= 0 {
fromDate = Calendar.current.date(byAdding: .year, value: -1, to: Date())!
} else {
fromDate = Calendar.current.date(byAdding: .month, value: -3, to: Date())!
}

let task = URLSession.shared.dataTask(with: urlRequest(participantId: participantId, fromDate: fromDate)) { [weak self] data, response, error in

if let data, let urlResponse = response as? HTTPURLResponse {


let decoder = JSONDecoder()
let formatter = ISO8601DateFormatter()
decoder.dateDecodingStrategy = .formatted(formatter)
do {
let responseData = try decoder.decode(ActivityEventResponse.self, from: data)

let reslut = self?.findCurentAndLongestStreak(dates: responseData.dates ?? [])


UserDefaults.standard.streakDataCurrentShared = reslut?.0 ?? 0
UserDefaults.standard.streakDataMaxShared = reslut?.1 ?? 0

self?.setLongestStreak(streak: reslut?.1 ?? 0, participantId: participantId)

if let reslut {
StreakWidgetHelper.cachedEntry = reslut
}
completion?(responseData.dates)


} catch (let err) {
completion?(nil)
}
Expand Down Expand Up @@ -87,12 +106,21 @@ public class StreakWidgetHelper {
// }
}

func urlRequest(participantId: String) -> URLRequest {

func urlRequest(participantId: String, fromDate: Date) -> URLRequest {
//from to timestamp
let endPoint = String(format: Endpoint.activityEvent.rawValue, participantId)

let baseURL = URL(string: LampURL.baseURLString)!
var request = URLRequest(url: baseURL.appendingPathComponent(endPoint))
let fullurl = baseURL.appendingPathComponent(endPoint)
//https://api-staging.lamp.digital/participant/U2604494105/activity_event?from=1719945000516&to=1720031400516
var components = URLComponents(string: fullurl.absoluteString)!

components.queryItems = [
URLQueryItem(name: "from", value: String(fromDate.timeInMilliSeconds)),
//URLQueryItem(name: "to", value: String(Date().timeInMilliSeconds)),
]
let url = components.url!

var request = URLRequest(url: url)
request.httpMethod = "GET"
var requestHeaders = [String: String]()
requestHeaders["Content-Type"] = "application/json"
Expand Down Expand Up @@ -123,14 +151,12 @@ public class StreakWidgetHelper {
var uniqueDaysArray = [Date]()

let dateFormatter = DateFormatter()
dateFormatter.timeZone = .current
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd"

for date in dates {
print("date = \(date)")
let dayString = dateFormatter.string(from: date)
print("dayString = \(dayString)")
if !uniqueDaysSet.contains(dayString) {
uniqueDaysSet.insert(dayString)
uniqueDaysArray.append(dateFormatter.date(from: dayString)!)
Expand Down
Loading

0 comments on commit 1bd051b

Please sign in to comment.