Refresh interval string localizations
This commit is contained in:
@@ -10,15 +10,18 @@ and this project does NOT adhere to [Semantic Versioning](https://semver.org/spe
|
|||||||
- Show users any 5xx server error response and extracted failure reason
|
- Show users any 5xx server error response and extracted failure reason
|
||||||
- 5xx server errors have a reload button which will initiate a new download with the same URL
|
- 5xx server errors have a reload button which will initiate a new download with the same URL
|
||||||
- Adding feed: Cmd+R will reload the same URL
|
- Adding feed: Cmd+R will reload the same URL
|
||||||
- Settings, Feeds: Cmd+R will reload the data source
|
- Settings, Feeds: Cmd+R will reload the data source
|
||||||
|
- Refresh interval string localizations
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Changed error message text when user cancels creation of new feed item
|
- Changed error message text when user cancels creation of new feed item
|
||||||
- Comparing existing articles with nonexistent guid and link
|
- Comparing existing articles with nonexistent guid and link
|
||||||
- Adding feed: If URLs can't be resolved in the first run (5xx error), try a second time. E.g., 'Done' click (issue: #5)
|
- Adding feed: If URLs can't be resolved in the first run (5xx error), try a second time. E.g., 'Done' click (issue: #5)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Interface builder files replaced with code equivalent
|
- Interface builder files replaced with code equivalent
|
||||||
|
- Settings, Feeds: Single add button for feeds, groups, and separators
|
||||||
|
- Refresh interval hotkeys set to: Cmd+1 … Cmd+6
|
||||||
|
|
||||||
|
|
||||||
## [0.9.4] - 2019-04-02
|
## [0.9.4] - 2019-04-02
|
||||||
|
|||||||
@@ -48,5 +48,4 @@ typedef NS_ENUM(int16_t, FeedGroupType) {
|
|||||||
- (BOOL)iterateSorted:(BOOL)ordered overDescendantFeeds:(void(^)(Feed *feed, BOOL* cancel))block;
|
- (BOOL)iterateSorted:(BOOL)ordered overDescendantFeeds:(void(^)(Feed *feed, BOOL* cancel))block;
|
||||||
// Printing
|
// Printing
|
||||||
- (NSString*)readableDescription;
|
- (NSString*)readableDescription;
|
||||||
- (nonnull NSString*)refreshString;
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -141,22 +141,10 @@
|
|||||||
/// @return Simplified description of the feed object.
|
/// @return Simplified description of the feed object.
|
||||||
- (NSString*)readableDescription {
|
- (NSString*)readableDescription {
|
||||||
switch (self.type) {
|
switch (self.type) {
|
||||||
|
case GROUP: return [NSString stringWithFormat:@"%@:", self.name];
|
||||||
|
case FEED: return [NSString stringWithFormat:@"%@ (%@)", self.name, self.feed.meta.url];
|
||||||
case SEPARATOR: return @"-------------";
|
case SEPARATOR: return @"-------------";
|
||||||
case GROUP: return [NSString stringWithFormat:@"%@", self.name];
|
|
||||||
case FEED:
|
|
||||||
return [NSString stringWithFormat:@"%@ (%@) - %@", self.name, self.feed.meta.url, [self refreshString]];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @return Formatted string for update interval ( e.g., @c 30m or @c 12h )
|
|
||||||
- (nonnull NSString*)refreshString {
|
|
||||||
if (self.type == FEED) {
|
|
||||||
int32_t refresh = self.feed.meta.refresh;
|
|
||||||
if (refresh <= 0)
|
|
||||||
return @"∞"; // ∞ ƒ Ø
|
|
||||||
return [NSDate stringForInterval:refresh rounded:NO];
|
|
||||||
}
|
|
||||||
return @"";
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -33,7 +33,6 @@
|
|||||||
if (self.errorCount < 0)
|
if (self.errorCount < 0)
|
||||||
self.errorCount = 0;
|
self.errorCount = 0;
|
||||||
int16_t n = self.errorCount + 1; // always increment errorCount (can be used to indicate bad feeds)
|
int16_t n = self.errorCount + 1; // always increment errorCount (can be used to indicate bad feeds)
|
||||||
// TODO: remove logging
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
NSLog(@"ERROR: Feed download failed: %@ (errorCount: %d)", self.url, n);
|
NSLog(@"ERROR: Feed download failed: %@ (errorCount: %d)", self.url, n);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -39,8 +39,10 @@ typedef NS_ENUM(int32_t, TimeUnitType) {
|
|||||||
|
|
||||||
|
|
||||||
@interface NSDate (Interval)
|
@interface NSDate (Interval)
|
||||||
+ (nonnull NSString*)stringForInterval:(Interval)intv rounded:(BOOL)flag;
|
+ (nullable NSString*)intStringForInterval:(Interval)intv;
|
||||||
+ (TimeUnitType)unitForInterval:(Interval)intv rounded:(BOOL)flag;
|
+ (nonnull NSString*)floatStringForInterval:(Interval)intv;
|
||||||
|
+ (nullable NSString*)stringForRemainingTime:(NSDate*)other;
|
||||||
|
+ (Interval)floatToIntInterval:(Interval)intv;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -24,8 +24,6 @@
|
|||||||
|
|
||||||
#import <QuartzCore/QuartzCore.h>
|
#import <QuartzCore/QuartzCore.h>
|
||||||
|
|
||||||
static const char _shortnames[] = {'y','w','d','h','m','s'};
|
|
||||||
static const char *_names[] = {"Years", "Weeks", "Days", "Hours", "Minutes", "Seconds"};
|
|
||||||
static const TimeUnitType _values[] = {
|
static const TimeUnitType _values[] = {
|
||||||
TimeUnitYears,
|
TimeUnitYears,
|
||||||
TimeUnitWeeks,
|
TimeUnitWeeks,
|
||||||
@@ -55,61 +53,58 @@ static const TimeUnitType _values[] = {
|
|||||||
|
|
||||||
@implementation NSDate (Interval)
|
@implementation NSDate (Interval)
|
||||||
|
|
||||||
/// If @c flag @c = @c YES, print @c 1.1f float string with single char unit: e.g., 3.3m, 1.7h.
|
/// Short interval formatter string (e.g., '30 min', '2 hrs')
|
||||||
+ (nonnull NSString*)stringForInterval:(Interval)intv rounded:(BOOL)flag {
|
+ (nullable NSString*)intStringForInterval:(Interval)intv {
|
||||||
if (flag) {
|
TimeUnitType unit = [self unitForInterval:intv];
|
||||||
unsigned short i = [self floatUnitIndexForInterval:abs(intv)];
|
Interval num = intv / unit;
|
||||||
return [NSString stringWithFormat:@"%1.1f%c", intv / (float)_values[i], _shortnames[i]];
|
NSDateComponents *dc = [[NSDateComponents alloc] init];
|
||||||
|
switch (unit) {
|
||||||
|
case TimeUnitSeconds: dc.second = num; break;
|
||||||
|
case TimeUnitMinutes: dc.minute = num; break;
|
||||||
|
case TimeUnitHours: dc.hour = num; break;
|
||||||
|
case TimeUnitDays: dc.day = num; break;
|
||||||
|
case TimeUnitWeeks: dc.weekOfMonth = num; break;
|
||||||
|
case TimeUnitYears: dc.year = num; break;
|
||||||
}
|
}
|
||||||
unsigned short i = [self exactUnitIndexForInterval:abs(intv)];
|
return [NSDateComponentsFormatter localizedStringFromDateComponents:dc unitsStyle:NSDateComponentsFormatterUnitsStyleShort];
|
||||||
return [NSString stringWithFormat:@"%d%c", intv / _values[i], _shortnames[i]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @return Highest non-zero unit ( @c flag=YES ). Or highest integer-dividable unit ( @c flag=NO ).
|
/// Print @c 1.1f float string with single char unit: e.g., 3.3m, 1.7h.
|
||||||
+ (TimeUnitType)unitForInterval:(Interval)intv rounded:(BOOL)flag {
|
+ (nonnull NSString*)floatStringForInterval:(Interval)intv {
|
||||||
if (flag) {
|
unsigned short i = [self floatUnitIndexForInterval:abs(intv)];
|
||||||
return _values[[self floatUnitIndexForInterval:abs(intv)]];
|
return [NSString stringWithFormat:@"%1.1f%c", intv / (float)_values[i], "ywdhms"[i]];
|
||||||
}
|
|
||||||
return _values[[self exactUnitIndexForInterval:abs(intv)]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @return Highest unit type that allows integer division. E.g., '61 minutes'.
|
/// Short interval formatter string for remaining time until @c other date
|
||||||
+ (unsigned short)exactUnitIndexForInterval:(Interval)intv {
|
+ (nullable NSString*)stringForRemainingTime:(NSDate*)other {
|
||||||
for (unsigned short i = 0; i < 5; i++)
|
NSDateComponentsFormatter *formatter = [[NSDateComponentsFormatter alloc] init];
|
||||||
if (intv % _values[i] == 0) return i;
|
formatter.unitsStyle = NSDateComponentsFormatterUnitsStyleShort; // e.g., '30 min'
|
||||||
return 5; // seconds
|
formatter.maximumUnitCount = 1;
|
||||||
|
return [formatter stringFromTimeInterval: other.timeIntervalSinceNow];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Round uneven intervals to highest unit interval. E.g., @c 1:40–>2:00 or @c 1:03–>1:00
|
||||||
|
+ (Interval)floatToIntInterval:(Interval)intv {
|
||||||
|
TimeUnitType unit = _values[[self floatUnitIndexForInterval:abs(intv)]];
|
||||||
|
return (Interval)(roundf((float)intv / unit) * unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @return Highest integer-dividable unit. E.g., '61 minutes'
|
||||||
|
+ (TimeUnitType)unitForInterval:(Interval)intv {
|
||||||
|
if (intv == 0) return TimeUnitMinutes; // fallback to 0 minutes
|
||||||
|
for (unsigned short i = 0; i < 5; i++) // try: years -> minutes
|
||||||
|
if (intv % _values[i] == 0) return _values[i];
|
||||||
|
return TimeUnitSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @return Highest non-zero unit type. Can be used with fractions e.g., '1.1 hours'.
|
/// @return Highest non-zero unit type. Can be used with fractions e.g., '1.1 hours'.
|
||||||
+ (unsigned short)floatUnitIndexForInterval:(Interval)intv {
|
+ (unsigned short)floatUnitIndexForInterval:(Interval)intv {
|
||||||
|
if (intv == 0) return 4; // fallback to 0 minutes
|
||||||
for (unsigned short i = 0; i < 5; i++)
|
for (unsigned short i = 0; i < 5; i++)
|
||||||
if (intv > _values[i]) return i;
|
if (intv > _values[i]) return i;
|
||||||
return 5; // seconds
|
return 5; // seconds
|
||||||
}
|
}
|
||||||
/* NOT USED
|
|
||||||
/// Convert any unit to the next smaller one. Unit does not have to be exact.
|
|
||||||
+ (TimeUnitType)smallerUnit:(TimeUnitType)unit {
|
|
||||||
if (unit <= TimeUnitHours) return TimeUnitSeconds;
|
|
||||||
if (unit <= TimeUnitDays) return TimeUnitMinutes; // > hours
|
|
||||||
if (unit <= TimeUnitWeeks) return TimeUnitHours; // > days
|
|
||||||
if (unit <= TimeUnitYears) return TimeUnitDays; // > weeks
|
|
||||||
return TimeUnitWeeks; // > years
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @return Formatted string from @c timeIntervalSinceNow.
|
|
||||||
- (nonnull NSString*)intervalStringWithDecimal:(BOOL)flag {
|
|
||||||
return [NSDate stringForInterval:(Interval)[self timeIntervalSinceNow] rounded:flag];
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @return Highest non-zero unit ( @c flag=YES ). Or highest integer-dividable unit ( @c flag=NO ).
|
|
||||||
- (TimeUnitType)unitWithDecimal:(BOOL)flag {
|
|
||||||
Interval absIntv = abs((Interval)[self timeIntervalSinceNow]);
|
|
||||||
if (flag) {
|
|
||||||
return _values[ [NSDate floatUnitIndexForInterval:absIntv] ];
|
|
||||||
}
|
|
||||||
return _values[ [NSDate exactUnitIndexForInterval:absIntv] ];
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
@@ -122,7 +117,7 @@ static const TimeUnitType _values[] = {
|
|||||||
|
|
||||||
/// Configure both @c NSControl elements based on the provided interval @c intv.
|
/// Configure both @c NSControl elements based on the provided interval @c intv.
|
||||||
+ (void)setInterval:(Interval)intv forPopup:(NSPopUpButton*)popup andField:(NSTextField*)field animate:(BOOL)flag {
|
+ (void)setInterval:(Interval)intv forPopup:(NSPopUpButton*)popup andField:(NSTextField*)field animate:(BOOL)flag {
|
||||||
TimeUnitType unit = [self unitForInterval:intv rounded:NO];
|
TimeUnitType unit = [self unitForInterval:intv];
|
||||||
int num = (int)(intv / unit);
|
int num = (int)(intv / unit);
|
||||||
if (flag && popup.selectedTag != unit) [self animateControlSize:popup];
|
if (flag && popup.selectedTag != unit) [self animateControlSize:popup];
|
||||||
if (flag && field.intValue != num) [self animateControlSize:field];
|
if (flag && field.intValue != num) [self animateControlSize:field];
|
||||||
@@ -133,11 +128,12 @@ static const TimeUnitType _values[] = {
|
|||||||
/// Insert all @c TimeUnitType items into popup button. Save unit value into @c tag attribute.
|
/// Insert all @c TimeUnitType items into popup button. Save unit value into @c tag attribute.
|
||||||
+ (void)populateUnitsMenu:(NSPopUpButton*)popup selected:(TimeUnitType)unit {
|
+ (void)populateUnitsMenu:(NSPopUpButton*)popup selected:(TimeUnitType)unit {
|
||||||
[popup removeAllItems];
|
[popup removeAllItems];
|
||||||
for (NSUInteger i = 0; i < 6; i++) {
|
[popup addItemsWithTitles:@[NSLocalizedString(@"Years", nil), NSLocalizedString(@"Weeks", nil),
|
||||||
[popup addItemWithTitle:[NSString stringWithUTF8String:_names[i]]];
|
NSLocalizedString(@"Days", nil), NSLocalizedString(@"Hours", nil),
|
||||||
NSMenuItem *item = popup.lastItem;
|
NSLocalizedString(@"Minutes", nil), NSLocalizedString(@"Seconds", nil)]];
|
||||||
[item setKeyEquivalent:[[NSString stringWithFormat:@"%c", _shortnames[i]] uppercaseString]];
|
for (int i = 0; i < 6; i++) {
|
||||||
item.tag = _values[i];
|
[popup itemAtIndex:i].tag = _values[i];
|
||||||
|
[popup itemAtIndex:i].keyEquivalent = [NSString stringWithFormat:@"%d", i+1]; // Cmd+1 .. Cmd+6
|
||||||
}
|
}
|
||||||
[popup selectItemWithTag:unit];
|
[popup selectItemWithTag:unit];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>7749</string>
|
<string>8018</string>
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||||
<key>LSUIElement</key>
|
<key>LSUIElement</key>
|
||||||
|
|||||||
@@ -87,10 +87,10 @@ NS_INLINE NSTextField* GrayLabel(NSString *text) {
|
|||||||
|
|
||||||
/// Inline button with tag equal to refresh interval. @c 16px height.
|
/// Inline button with tag equal to refresh interval. @c 16px height.
|
||||||
- (NSButton*)createInlineButton:(NSNumber*)num callback:(nullable id<RefreshIntervalButtonDelegate>)callback {
|
- (NSButton*)createInlineButton:(NSNumber*)num callback:(nullable id<RefreshIntervalButtonDelegate>)callback {
|
||||||
NSButton *button = [NSView inlineButton:[NSDate stringForInterval:num.intValue rounded:YES]];
|
NSButton *button = [NSView inlineButton: [NSDate floatStringForInterval:num.intValue]];
|
||||||
TimeUnitType unit = [NSDate unitForInterval:num.intValue rounded:YES];
|
Interval intv = [NSDate floatToIntInterval:num.intValue]; // rounded to highest unit
|
||||||
button.tag = (NSInteger)(roundf(num.floatValue / unit) * unit); // rounded interval
|
button.accessibilityTitle = [NSDate intStringForInterval:intv];
|
||||||
// TODO: accessibility title: readable interval string
|
button.tag = (NSInteger)intv;
|
||||||
if (callback) {
|
if (callback) {
|
||||||
[button action:@selector(refreshIntervalButtonClicked:) target:callback];
|
[button action:@selector(refreshIntervalButtonClicked:) target:callback];
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#import "OpmlExport.h"
|
#import "OpmlExport.h"
|
||||||
#import "FeedDownload.h"
|
#import "FeedDownload.h"
|
||||||
#import "SettingsFeedsView.h"
|
#import "SettingsFeedsView.h"
|
||||||
|
#import "NSDate+Ext.h"
|
||||||
|
|
||||||
@interface SettingsFeeds ()
|
@interface SettingsFeeds ()
|
||||||
@property (strong) SettingsFeedsView *view; // override super
|
@property (strong) SettingsFeedsView *view; // override super
|
||||||
@@ -37,7 +38,6 @@
|
|||||||
@property (strong) NSUndoManager *undoManager;
|
@property (strong) NSUndoManager *undoManager;
|
||||||
|
|
||||||
@property (strong) NSTimer *timerStatusInfo;
|
@property (strong) NSTimer *timerStatusInfo;
|
||||||
@property (strong) NSDateComponentsFormatter *intervalFormatter;
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation SettingsFeeds
|
@implementation SettingsFeeds
|
||||||
@@ -94,9 +94,6 @@ static NSString *dragNodeType = @"baRSS-feed-drag";
|
|||||||
/// Initialize status info timer
|
/// Initialize status info timer
|
||||||
- (void)viewWillAppear {
|
- (void)viewWillAppear {
|
||||||
[self.dataStore rearrangeObjects]; // needed to scroll outline view to top (if prefs open on another tab)
|
[self.dataStore rearrangeObjects]; // needed to scroll outline view to top (if prefs open on another tab)
|
||||||
self.intervalFormatter = [[NSDateComponentsFormatter alloc] init];
|
|
||||||
self.intervalFormatter.unitsStyle = NSDateComponentsFormatterUnitsStyleShort; // e.g., '30 min'
|
|
||||||
self.intervalFormatter.maximumUnitCount = 1;
|
|
||||||
self.timerStatusInfo = [NSTimer timerWithTimeInterval:NSTimeIntervalSince1970 target:self selector:@selector(keepTimerRunning) userInfo:nil repeats:YES];
|
self.timerStatusInfo = [NSTimer timerWithTimeInterval:NSTimeIntervalSince1970 target:self selector:@selector(keepTimerRunning) userInfo:nil repeats:YES];
|
||||||
[[NSRunLoop mainRunLoop] addTimer:self.timerStatusInfo forMode:NSRunLoopCommonModes];
|
[[NSRunLoop mainRunLoop] addTimer:self.timerStatusInfo forMode:NSRunLoopCommonModes];
|
||||||
// start spinner if update is in progress when preferences open
|
// start spinner if update is in progress when preferences open
|
||||||
@@ -108,7 +105,6 @@ static NSString *dragNodeType = @"baRSS-feed-drag";
|
|||||||
// in viewWillDisappear otherwise dealloc will not be called
|
// in viewWillDisappear otherwise dealloc will not be called
|
||||||
[self.timerStatusInfo invalidate];
|
[self.timerStatusInfo invalidate];
|
||||||
self.timerStatusInfo = nil;
|
self.timerStatusInfo = nil;
|
||||||
self.intervalFormatter = nil;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Callback method to update status info. Will be called more often when interval is getting shorter.
|
/// Callback method to update status info. Will be called more often when interval is getting shorter.
|
||||||
@@ -120,14 +116,11 @@ static NSString *dragNodeType = @"baRSS-feed-drag";
|
|||||||
self.view.status.stringValue = @"";
|
self.view.status.stringValue = @"";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (nextFire > 60) { // update 1/min
|
self.view.status.stringValue = [NSString stringWithFormat:NSLocalizedString(@"Next update in %@", nil),
|
||||||
nextFire = fmod(nextFire, 60); // next update will align with minute
|
[NSDate stringForRemainingTime:date]];
|
||||||
} else {
|
// Next update is aligned with minute (fmod) else update 1/sec
|
||||||
nextFire = 1; // update 1/sec
|
NSDate *nextUpdate = [NSDate dateWithTimeIntervalSinceNow: (nextFire > 60 ? fmod(nextFire, 60) : 1)];
|
||||||
}
|
[self.timerStatusInfo setFireDate:nextUpdate];
|
||||||
NSString *str = [self.intervalFormatter stringFromTimeInterval: date.timeIntervalSinceNow];
|
|
||||||
self.view.status.stringValue = [NSString stringWithFormat:NSLocalizedString(@"Next update in %@", nil), str];
|
|
||||||
[self.timerStatusInfo setFireDate:[NSDate dateWithTimeIntervalSinceNow: nextFire]];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,7 @@
|
|||||||
|
|
||||||
NSTableColumn *colRefresh = [[NSTableColumn alloc] initWithIdentifier:CustomCellRefresh];
|
NSTableColumn *colRefresh = [[NSTableColumn alloc] initWithIdentifier:CustomCellRefresh];
|
||||||
colRefresh.title = NSLocalizedString(@"Refresh", nil);
|
colRefresh.title = NSLocalizedString(@"Refresh", nil);
|
||||||
colRefresh.width = 50;
|
colRefresh.width = 60;
|
||||||
colRefresh.resizingMask = NSTableColumnNoResizing;
|
colRefresh.resizingMask = NSTableColumnNoResizing;
|
||||||
[outline addTableColumn:colRefresh];
|
[outline addTableColumn:colRefresh];
|
||||||
|
|
||||||
@@ -224,15 +224,19 @@ NSUserInterfaceItemIdentifier const CustomCellRefresh = @"RefreshColumnCell";
|
|||||||
self = [super initWithFrame:frameRect];
|
self = [super initWithFrame:frameRect];
|
||||||
self.identifier = CustomCellRefresh;
|
self.identifier = CustomCellRefresh;
|
||||||
self.textField = [[[[NSView label:@""] textRight] placeIn:self x:0 yTop:0] sizeToRight:0];
|
self.textField = [[[[NSView label:@""] textRight] placeIn:self x:0 yTop:0] sizeToRight:0];
|
||||||
self.textField.accessibilityLabel = NSLocalizedString(@"Refresh interval", nil);
|
self.textField.accessibilityTitle = @" "; // otherwise groups and separators will say 'text'
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setObjectValue:(FeedGroup*)fg {
|
- (void)setObjectValue:(FeedGroup*)fg {
|
||||||
NSString *str = [fg refreshString];
|
NSString *str = @"";
|
||||||
|
if (fg.type == FEED) {
|
||||||
|
int32_t refresh = fg.feed.meta.refresh;
|
||||||
|
str = (refresh <= 0 ? @"∞" : [NSDate intStringForInterval:refresh]); // ∞ ƒ Ø
|
||||||
|
}
|
||||||
self.textField.objectValue = str;
|
self.textField.objectValue = str;
|
||||||
// TODO: accessibility title: readable interval string
|
|
||||||
self.textField.textColor = (str.length > 1 ? [NSColor controlTextColor] : [NSColor disabledControlTextColor]);
|
self.textField.textColor = (str.length > 1 ? [NSColor controlTextColor] : [NSColor disabledControlTextColor]);
|
||||||
|
self.textField.accessibilityLabel = (str.length > 1 ? NSLocalizedString(@"Refresh interval", nil) : nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
Reference in New Issue
Block a user