-
Notifications
You must be signed in to change notification settings - Fork 10
date picker wraps around to 1 for the first of the current month #496
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
Merged
theospears
merged 5 commits into
beeminder:master
from
krugerk:bugfix/issue386-date-picker-wraps-around-to-1-for-the-first-of-the-current-month
Nov 15, 2024
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
9a2f104
using Calendar rather than NSCalendar directly
krugerk d0cb453
Date picker wraps around to 1 for the first of the current month
krugerk edcfe37
avoiding recreating the urtext date formatter so often
krugerk 9321278
avoiding recreating the urtext date formatter so often
krugerk e3b6e51
clean code
krugerk File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -40,6 +40,9 @@ class GoalViewController: UIViewController, UIScrollViewDelegate, DatapointTabl | |
| fileprivate let headerWidth = Double(1.0/3.0) | ||
| fileprivate let viewGoalActivityType = "com.beeminder.viewGoal" | ||
|
|
||
| // date corresponding to the datapoint to be created | ||
| private var date: Date = Date() | ||
|
|
||
| init(goal: Goal) { | ||
| self.goal = goal | ||
| super.init(nibName: nil, bundle: nil) | ||
|
|
@@ -272,7 +275,7 @@ class GoalViewController: UIViewController, UIScrollViewDelegate, DatapointTabl | |
| } | ||
|
|
||
| self.navigationItem.rightBarButtonItems = [UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(self.actionButtonPressed))] | ||
| if (!self.goal.hideDataEntry) { | ||
| if !self.goal.hideDataEntry { | ||
| self.navigationItem.rightBarButtonItems?.append(UIBarButtonItem(image: UIImage(named: "Timer"), style: .plain, target: self, action: #selector(self.timerButtonPressed))) | ||
| } | ||
|
|
||
|
|
@@ -368,12 +371,14 @@ class GoalViewController: UIViewController, UIScrollViewDelegate, DatapointTabl | |
| var components = DateComponents() | ||
| components.day = Int(self.dateStepper.value) | ||
|
|
||
| let newDate = (calendar as NSCalendar?)?.date(byAdding: components, to: Date(), options: []) | ||
| let now = Date() | ||
| guard let newDate = calendar.date(byAdding: components, to: now) else { return } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: This seems like the return here should never happen. I like logging a warning in these cases. |
||
| self.date = newDate | ||
|
|
||
| let isDifferentYear = calendar.component(.year, from: now) != calendar.component(.year, from: date) | ||
| let isDifferentMonth = calendar.component(.month, from: now) != calendar.component(.month, from: date) | ||
|
|
||
| let formatter = DateFormatter() | ||
| formatter.locale = Locale(identifier: "en_US") | ||
| formatter.dateFormat = "d" | ||
| self.dateTextField.text = formatter.string(from: newDate!) | ||
| self.dateTextField.text = DateFormatter.dateTextFieldString(from: self.date, isDifferentYear: isDifferentYear, isDifferentMonth: isDifferentMonth) | ||
| } | ||
|
|
||
| func setValueTextField() { | ||
|
|
@@ -417,12 +422,12 @@ class GoalViewController: UIViewController, UIScrollViewDelegate, DatapointTabl | |
| } | ||
|
|
||
| func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { | ||
| if (textField.isEqual(self.valueTextField)) { | ||
| if textField.isEqual(self.valueTextField) { | ||
| // Only allow a single decimal separator (, or .) | ||
| if textField.text!.components(separatedBy: ".").count > 1 { | ||
| if string == "." || string == "," { return false } | ||
| } | ||
| if (string == ",") { | ||
| if string == "," { | ||
| textField.text = textField.text! + "." | ||
| return false | ||
| } | ||
|
|
@@ -436,9 +441,9 @@ class GoalViewController: UIViewController, UIScrollViewDelegate, DatapointTabl | |
| } | ||
| return true | ||
| } | ||
|
|
||
| func urtextFromTextFields() -> String { | ||
| return "\(self.dateTextField.text!) \(self.valueTextField.text!) \"\(self.commentTextField.text!)\"" | ||
| private var urtext: String { | ||
| return "\(DateFormatter.urtextDateString(from: self.date)) \(self.valueTextField.text!) \"\(self.commentTextField.text!)\"" | ||
krugerk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| @objc func submitDatapoint() { | ||
|
|
@@ -450,7 +455,7 @@ class GoalViewController: UIViewController, UIScrollViewDelegate, DatapointTabl | |
| self.scrollView.scrollRectToVisible(CGRect(x: 0, y: 0, width: 0, height: 0), animated: true) | ||
|
|
||
| do { | ||
| let _ = try await ServiceLocator.requestManager.addDatapoint(urtext: self.urtextFromTextFields(), slug: self.goal.slug) | ||
| let _ = try await ServiceLocator.requestManager.addDatapoint(urtext: self.urtext, slug: self.goal.slug) | ||
| self.commentTextField.text = "" | ||
krugerk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| try await updateGoalAndInterface() | ||
|
|
@@ -506,3 +511,50 @@ class GoalViewController: UIViewController, UIScrollViewDelegate, DatapointTabl | |
| controller.dismiss(animated: true, completion: nil) | ||
| } | ||
| } | ||
|
|
||
|
|
||
| private extension DateFormatter { | ||
| private static let urtextDateFormatter: DateFormatter = { | ||
| let formatter = DateFormatter() | ||
| formatter.locale = Locale(identifier: "en_US") | ||
| formatter.dateFormat = "yyyy MM dd" | ||
| return formatter | ||
| }() | ||
|
|
||
| static func urtextDateString(from date: Date) -> String { | ||
| urtextDateFormatter.string(from: date) | ||
| } | ||
| } | ||
|
|
||
| private extension DateFormatter { | ||
| private static let newDatapointDateDifferentYearDateFormatter: DateFormatter = { | ||
| let formatter = DateFormatter() | ||
| formatter.locale = Locale(identifier: "en_US") | ||
| formatter.dateFormat = "yyyy-MM-dd" | ||
| return formatter | ||
| }() | ||
|
|
||
| private static let newDatapointDateDifferentMonthDateFormatter: DateFormatter = { | ||
| let formatter = DateFormatter() | ||
| formatter.locale = Locale(identifier: "en_US") | ||
| formatter.dateFormat = "MMM d" | ||
| return formatter | ||
| }() | ||
|
|
||
| private static let newDatapointDateWithinSameMonthDateFormatter: DateFormatter = { | ||
| let formatter = DateFormatter() | ||
| formatter.locale = Locale(identifier: "en_US") | ||
| formatter.dateFormat = "d" | ||
| return formatter | ||
| }() | ||
|
|
||
| static func dateTextFieldString(from date: Date, isDifferentYear: Bool, isDifferentMonth: Bool) -> String { | ||
| if isDifferentYear { | ||
| return newDatapointDateDifferentYearDateFormatter.string(from: date) | ||
| } else if isDifferentMonth { | ||
| return newDatapointDateDifferentMonthDateFormatter.string(from: date) | ||
| } else { | ||
| return newDatapointDateWithinSameMonthDateFormatter.string(from: date) | ||
| } | ||
| } | ||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does surprising things if you have the view open and midnight rolls around. But this PR doesn't change that weird behavior, it was always there.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True. The app will work with the data it has from the time it last fetched it. One can use other means to adjust the deadline and the one client might not know about it while it is at the timer screen, add data screen, or edit data screen. (See #26)
Is the server posting to the app via remote notification that a goal has been updated? Does the app still need to fetch (pull) to find out?