Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 7 additions & 3 deletions BeeSwift/Settings/EditDefaultNotificationsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,14 @@ class EditDefaultNotificationsViewController: EditNotificationsViewController {
hud.hide(animated: true, afterDelay: 0.5)
} catch {
logger.error("Error setting default alert start: \(error)")
hud.hide(animated: true)
hud.hide(animated: true, afterDelay: 0.5)
}

case .deadline:
self.updateDeadlineLabel(self.midnightOffsetFromTimePickerView())
let params = ["default_deadline" : self.midnightOffsetFromTimePickerView()]
let deadline = self.midnightOffsetFromTimePickerView()
self.updateDeadlineLabel(deadline)
let params = ["default_deadline" : deadline]

do {
let _ = try await requestManager.put(url: "api/v1/users/{username}.json", parameters: params)
try await goalManager.refreshGoals()
Expand All @@ -86,6 +89,7 @@ class EditDefaultNotificationsViewController: EditNotificationsViewController {
logger.error("Error setting default deadline: \(error)")
hud.hide(animated: true, afterDelay: 0.5)
}

case .none:
hud.hide(animated: true)
}
Expand Down
5 changes: 3 additions & 2 deletions BeeSwift/Settings/EditGoalNotificationsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,10 @@ class EditGoalNotificationsViewController : EditNotificationsViewController {
}
}
if self.timePickerEditingMode == .deadline {
self.updateDeadlineLabel(self.midnightOffsetFromTimePickerView())
let deadline = self.deadlineFromTimePickerView
self.updateDeadlineLabel(deadline)
do {
let params = ["deadline" : self.midnightOffsetFromTimePickerView(), "use_defaults" : false]
let params = ["deadline" : deadline, "use_defaults" : false]
let _ = try await self.requestManager.put(url: "api/v1/users/{username}/goals/\(self.goal.slug).json", parameters: params)
try await self.goalManager.refreshGoal(self.goal.objectID)

Expand Down
74 changes: 49 additions & 25 deletions BeeSwift/Settings/EditNotificationsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,13 @@ class EditNotificationsViewController: UIViewController {
self.deadlineLabel.text = "Goal deadline: \(self.stringFromMidnightOffset(deadline))"
}

func stringFromMidnightOffset(_ offset : Int) -> NSString {
func stringFromMidnightOffset(_ offset : Int) -> String {
let date = Date(timeInterval: Double(offset), since: Calendar.current.startOfDay(for: Date()))
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: self.use24HourTime() ? "en_UK" : "en_US")
dateFormatter.timeStyle = DateFormatter.Style.short
dateFormatter.dateStyle = DateFormatter.Style.none
return dateFormatter.string(from: date) as NSString
return dateFormatter.string(from: date)
}

func updateLeadTimeLabel() {
Expand Down Expand Up @@ -160,29 +160,34 @@ class EditNotificationsViewController: UIViewController {
func setTimePickerComponents(_ offsetFromMidnight : Int) {
var hour = offsetFromMidnight / 3600
var minute = (offsetFromMidnight % 3600) / 60

// Normalize the time to ensure positive values
if hour < 0 || minute < 0 {
// For times like 23:59 which come in as -1 minutes before midnight
// we need to convert to the equivalent hour before midnight
let totalMinutes = hour * 60 + minute
let normalizedMinutes = (totalMinutes + 24 * 60) % (24 * 60)
hour = normalizedMinutes / 60
minute = normalizedMinutes % 60
}

if self.use24HourTime() {
if hour < 0 { hour = 25 + hour }
if minute < 0 { minute = 60 + minute }
self.timePickerView.selectRow(hour, inComponent: 0, animated: true)
self.timePickerView.selectRow(minute, inComponent: 1, animated: true)
}
else {
if hour > 12 {
self.timePickerView.selectRow(1, inComponent: 2, animated: true)
self.timePickerView.selectRow(hour - 12, inComponent: 0, animated: true)
}
else {
self.timePickerView.selectRow(hour, inComponent: 0, animated: true)
}
self.timePickerView.selectRow(minute, inComponent: 1, animated: true)
} else {
// Convert to 12-hour format
let isPM = hour >= 12
let displayHour = hour % 12
self.timePickerView.selectRow(displayHour == 0 ? 12 : displayHour, inComponent: 0, animated: true)
self.timePickerView.selectRow(isPM ? 1 : 0, inComponent: 2, animated: true)
}
self.timePickerView.selectRow(minute, inComponent: 1, animated: true)
}
}

extension EditNotificationsViewController : UIPickerViewDataSource, UIPickerViewDelegate {
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if component == 0 {
return Bool(self.use24HourTime()) ? 24 : 12
return self.use24HourTime() ? 24 : 12
}
else if component == 1 {
return 60
Expand All @@ -191,19 +196,38 @@ extension EditNotificationsViewController : UIPickerViewDataSource, UIPickerView
}

func midnightOffsetFromTimePickerView() -> Int {
let minute = NSNumber(value: self.timePickerView.selectedRow(inComponent: 1))
let hour = self.hourFromTimePicker()
let minute = self.timePickerView.selectedRow(inComponent: 1)
let hour = self.hour24FromPicker

return 3600*hour.intValue + 60*minute.intValue
return 3600*hour + 60*minute
}

// we're doing this instead of just using a UIDatePicker so that we can use the
// Beeminder font in the picker instead of the system font
func hourFromTimePicker() -> NSNumber {
if self.use24HourTime() || self.timePickerView.selectedRow(inComponent: 2) == 0 {
return NSNumber(value: self.timePickerView.selectedRow(inComponent: 0))
// Convert to deadline format:
// - Times from midnight to 6am (0-6) stay positive
// - Times from 7am to midnight (7-23) become negative offsets from next midnight
var deadlineFromTimePickerView: Int {
let hour24 = hour24FromPicker
let selectedMinute = self.timePickerView.selectedRow(inComponent: 1)

let totalSeconds = 3600 * hour24 + 60 * selectedMinute

if hour24 <= 6 {
return totalSeconds // Keep positive for early morning hours
} else {
return totalSeconds - (24 * 3600) // Convert to negative offset from next midnight
}
return NSNumber(value: self.timePickerView.selectedRow(inComponent: 0) + 12)
}

var hour24FromPicker: Int {
let selectedHour = self.timePickerView.selectedRow(inComponent: 0)
// 24h
guard !self.use24HourTime() else { return selectedHour }

// 12h am
guard self.timePickerView.selectedRow(inComponent: 2) == 1 else { return selectedHour }

// 12h pm
return selectedHour == 12 ? 12 : selectedHour + 12
}

func numberOfComponents(in pickerView: UIPickerView) -> Int {
Expand Down
Loading