Skip to content

Commit

Permalink
feat: allow hiding unit letter and symbol (separately each)
Browse files Browse the repository at this point in the history
  • Loading branch information
eugenesvk committed Jul 14, 2023
1 parent d6cd18b commit 4c11531
Show file tree
Hide file tree
Showing 12 changed files with 125 additions and 19 deletions.
6 changes: 4 additions & 2 deletions DatWeatherDoe/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,15 @@ class AppDelegate: NSObject, NSApplicationDelegate {
extension AppDelegate: WeatherViewModelDelegate {
func didUpdateWeatherData(_ data: WeatherData) {
viewModel.updateCityWith(cityId: data.cityId)

let measurementUnit = MeasurementUnit(rawValue: configManager.measurementUnit) ?? .imperial
menuBarManager.updateMenuBarWith(
weatherData: data,
options: .init(
unit: measurementUnit,
isRoundingOff: configManager.isRoundingOffData
isRoundingOff: configManager.isRoundingOffData,
isUnitLetterOff: configManager.isUnitLetterOff,
isUnitSymbolOff: configManager.isUnitSymbolOff
)
)
}
Expand Down
10 changes: 10 additions & 0 deletions DatWeatherDoe/Config/ConfigManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ protocol ConfigManagerType: AnyObject {
var isShowingWeatherIcon: Bool { get set }
var isShowingHumidity: Bool { get set }
var isRoundingOffData: Bool { get set }
var isUnitLetterOff: Bool { get set }
var isUnitSymbolOff: Bool { get set }
var isWeatherConditionAsTextEnabled: Bool { get set }
}

Expand All @@ -29,6 +31,8 @@ final class ConfigManager: ConfigManagerType {
case isShowingWeatherIcon
case isShowingHumidity
case isRoundingOffData
case isUnitLetterOff
case isUnitSymbolOff
case isWeatherConditionAsTextEnabled
}

Expand Down Expand Up @@ -62,6 +66,12 @@ final class ConfigManager: ConfigManagerType {
@Storage(key: DefaultsKeys.isRoundingOffData.rawValue, defaultValue: false)
public var isRoundingOffData: Bool

@Storage(key: DefaultsKeys.isUnitLetterOff.rawValue, defaultValue: false)
public var isUnitLetterOff: Bool

@Storage(key: DefaultsKeys.isUnitSymbolOff.rawValue, defaultValue: false)
public var isUnitSymbolOff: Bool

@Storage(
key: DefaultsKeys.isWeatherConditionAsTextEnabled.rawValue,
defaultValue: false
Expand Down
4 changes: 4 additions & 0 deletions DatWeatherDoe/UI/Configure/ConfigurationCommitter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,15 @@ final class ConfigurationCommitter {
refreshInterval: RefreshInterval,
isShowingHumidity: Bool,
isRoundingOffData: Bool,
isUnitLetterOff: Bool,
isUnitSymbolOff: Bool,
isWeatherConditionAsTextEnabled: Bool
) {
configManager.refreshInterval = refreshInterval.rawValue
configManager.isShowingHumidity = isShowingHumidity
configManager.isRoundingOffData = isRoundingOffData
configManager.isUnitLetterOff = isUnitLetterOff
configManager.isUnitSymbolOff = isUnitSymbolOff
configManager.isWeatherConditionAsTextEnabled = isWeatherConditionAsTextEnabled
}
}
12 changes: 12 additions & 0 deletions DatWeatherDoe/UI/Configure/ConfigureView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,18 @@ struct ConfigureView: View {
Toggle(isOn: $viewModel.isRoundingOffData) {}
}

HStack {
Text(LocalizedStringKey("Hide unit letter"))
Spacer()
Toggle(isOn: $viewModel.isUnitLetterOff) {}
}

HStack {
Text(LocalizedStringKey("Hide unit ° symbol"))
Spacer()
Toggle(isOn: $viewModel.isUnitSymbolOff) {}
}

HStack {
Text(LocalizedStringKey("Weather Condition (as text)"))
Spacer()
Expand Down
16 changes: 16 additions & 0 deletions DatWeatherDoe/UI/Configure/ConfigureViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,18 @@ final class ConfigureViewModel: ObservableObject {
}
}

@Published var isUnitLetterOff: Bool {
didSet {
configManager.isUnitLetterOff = isUnitLetterOff
}
}

@Published var isUnitSymbolOff: Bool {
didSet {
configManager.isUnitSymbolOff = isUnitSymbolOff
}
}

@Published var isWeatherConditionAsTextEnabled: Bool {
didSet {
configManager.isWeatherConditionAsTextEnabled = isWeatherConditionAsTextEnabled
Expand Down Expand Up @@ -86,6 +98,8 @@ final class ConfigureViewModel: ObservableObject {
isShowingWeatherIcon = configManager.isShowingWeatherIcon
isShowingHumidity = configManager.isShowingHumidity
isRoundingOffData = configManager.isRoundingOffData
isUnitLetterOff = configManager.isUnitLetterOff
isUnitSymbolOff = configManager.isUnitSymbolOff
isWeatherConditionAsTextEnabled = configManager.isWeatherConditionAsTextEnabled

updateWeatherSource()
Expand Down Expand Up @@ -116,6 +130,8 @@ final class ConfigureViewModel: ObservableObject {
refreshInterval: refreshInterval,
isShowingHumidity: isShowingHumidity,
isRoundingOffData: isRoundingOffData,
isUnitLetterOff: isUnitLetterOff,
isUnitSymbolOff: isUnitSymbolOff,
isWeatherConditionAsTextEnabled: isWeatherConditionAsTextEnabled
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ final class TemperatureForecastTextBuilder {
TemperatureHelpers.getTemperatureWithDegrees(
temperature,
unit: options.unit,
isRoundingOff: options.isRoundingOff
isRoundingOff: options.isRoundingOff,
isUnitLetterOff: options.isUnitLetterOff,
isUnitSymbolOff: options.isUnitSymbolOff
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ final class TemperatureFormatter {
return formatter
}()

func getFormattedTemperatureString(_ temperature: Double, isRoundingOff: Bool) -> String? {
func getFormattedTemperatureString(_ temperature: Double,
isRoundingOff: Bool,
isUnitLetterOff: Bool,
isUnitSymbolOff: Bool) -> String? {
setupTemperatureRounding(isRoundingOff: isRoundingOff)
return formatTemperatureString(temperature)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,59 @@ final class TemperatureHelpers {
class func getTemperatureWithDegrees(
_ temperature: Double,
unit: TemperatureUnit,
isRoundingOff: Bool
isRoundingOff: Bool,
isUnitLetterOff: Bool,
isUnitSymbolOff: Bool
) -> String? {
guard let temperatureString = getFormattedString(
temperature: temperature,
isRoundingOff: isRoundingOff
isRoundingOff: isRoundingOff,
isUnitLetterOff: isUnitLetterOff,
isUnitSymbolOff: isUnitSymbolOff
) else {
return nil
}

return combineTemperatureWithUnitDegrees(
temperature: temperatureString,
unit: unit.unitString
unit: unit.unitString,
isUnitLetterOff: isUnitLetterOff,
isUnitSymbolOff: isUnitSymbolOff
)
}

private class func getFormattedString(
temperature: Double,
isRoundingOff: Bool
isRoundingOff: Bool,
isUnitLetterOff: Bool,
isUnitSymbolOff: Bool
) -> String? {
TemperatureFormatter().getFormattedTemperatureString(
temperature,
isRoundingOff: isRoundingOff
isRoundingOff: isRoundingOff,
isUnitLetterOff: isUnitLetterOff,
isUnitSymbolOff: isUnitSymbolOff
)
}

private class func combineTemperatureWithUnitDegrees(
temperature: String,
unit: String
unit: String,
isUnitLetterOff: Bool,
isUnitSymbolOff: Bool
) -> String {
[temperature, unit].joined(separator: degreeString)
if isUnitLetterOff {
if isUnitSymbolOff {
return [temperature, ""].joined(separator: "" )
} else {
return [temperature, ""].joined(separator: degreeString)
}
} else {
if isUnitSymbolOff {
return [temperature, unit].joined(separator: "" )
} else {
return [temperature, unit].joined(separator: degreeString)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ final class TemperatureTextBuilder {
struct Options {
let unit: TemperatureUnit
let isRoundingOff: Bool
let isUnitLetterOff: Bool
let isUnitSymbolOff: Bool
}

private let initial: String?
Expand All @@ -32,7 +34,9 @@ final class TemperatureTextBuilder {
let temperature = TemperatureHelpers.getTemperatureWithDegrees(
response.temperatureData.temperature,
unit: options.unit,
isRoundingOff: options.isRoundingOff
isRoundingOff: options.isRoundingOff,
isUnitLetterOff: options.isUnitLetterOff,
isUnitSymbolOff: options.isUnitSymbolOff
)
return [initial, temperature]
.compactMap { $0 }
Expand Down
8 changes: 7 additions & 1 deletion DatWeatherDoe/UI/Menu Bar/StatusItemManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ final class StatusItemManager {
struct Options {
let unit: MeasurementUnit
let isRoundingOff: Bool
let isUnitLetterOff: Bool
let isUnitSymbolOff: Bool
}

var button: NSStatusBarButton? { statusItem.button }
Expand Down Expand Up @@ -125,7 +127,11 @@ final class StatusItemManager {
private func getWeatherTextFrom(weatherData: WeatherData, options: Options) -> String {
TemperatureForecastTextBuilder(
temperatureData: weatherData.temperatureData,
options: .init(unit: options.unit.temperatureUnit, isRoundingOff: options.isRoundingOff)
options: .init(unit: options.unit.temperatureUnit,
isRoundingOff: options.isRoundingOff,
isUnitLetterOff: options.isUnitLetterOff,
isUnitSymbolOff: options.isUnitSymbolOff
)
).build()
}

Expand Down
12 changes: 7 additions & 5 deletions DatWeatherDoe/ViewModel/WeatherViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import OSLog
final class WeatherViewModel: WeatherViewModelType {

weak var delegate: WeatherViewModelDelegate?

private let configManager: ConfigManagerType
private let errorLabels = ErrorLabels()
private let weatherTimerSerialQueue = DispatchQueue(label: "Weather Timer Serial Queue")
Expand Down Expand Up @@ -55,7 +55,7 @@ final class WeatherViewModel: WeatherViewModelType {

private func getWeatherWithSelectedSource() {
let weatherSource = WeatherSource(rawValue: configManager.weatherSource) ?? .location

switch weatherSource {
case .location:
getWeatherAfterUpdatingLocation()
Expand All @@ -75,7 +75,7 @@ final class WeatherViewModel: WeatherViewModelType {
delegate?.didFailToUpdateWeatherData(errorLabels.latLongErrorString)
return
}

weatherTask?.cancel()
weatherTask = Task {
do {
Expand Down Expand Up @@ -135,7 +135,9 @@ final class WeatherViewModel: WeatherViewModelType {
isWeatherConditionAsTextEnabled: configManager.isWeatherConditionAsTextEnabled,
temperatureOptions: .init(
unit: unit.temperatureUnit,
isRoundingOff: configManager.isRoundingOffData
isRoundingOff: configManager.isRoundingOffData,
isUnitLetterOff: configManager.isUnitLetterOff,
isUnitSymbolOff: configManager.isUnitSymbolOff
),
isShowingHumidity: configManager.isShowingHumidity
)
Expand All @@ -155,7 +157,7 @@ final class WeatherViewModel: WeatherViewModelType {
}
}
}

private var measurementUnit: MeasurementUnit {
MeasurementUnit(rawValue: configManager.measurementUnit) ?? .imperial
}
Expand Down
21 changes: 21 additions & 0 deletions DatWeatherDoeTests/Config/ConfigManagerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,33 @@ final class ConfigManagerTests: XCTestCase {
XCTAssertEqual(configManager.isRoundingOffData, false)
}

func testDefaultUnitLetterOffOffData() {
XCTAssertEqual(configManager.isUnitLetterOff, false)
}

func testDefaultisUnitSymbolOff() {
XCTAssertEqual(configManager.isUnitSymbolOff, false)
}

func testRoundingOffDataSaved() {
XCTAssertEqual(configManager.isRoundingOffData, false)
configManager.isRoundingOffData = true
XCTAssertEqual(configManager.isRoundingOffData, true)
}

func testUnitLetterOffSaved() {
XCTAssertEqual(configManager.isUnitLetterOff, false)
configManager.isUnitLetterOff = true
XCTAssertEqual(configManager.isUnitLetterOff, true)
}

func testUnitSymbolOffSaved() {
XCTAssertEqual(configManager.isUnitSymbolOff, false)
configManager.isUnitSymbolOff = true
XCTAssertEqual(configManager.isUnitSymbolOff, true)
}


func testWeatherConditionAsTextDefault() {
XCTAssertEqual(configManager.isWeatherConditionAsTextEnabled, false)
}
Expand Down

0 comments on commit 4c11531

Please sign in to comment.