Commit 4a0e1f92 by Demid Merzlyakov

IOS-22: Smart text: ongoing precipitation.

parent f8b0819d
......@@ -8,29 +8,62 @@
import Foundation
private enum Macro: String {
case feelsLikeTemp = "#FEELS_LIKE_TEMP"
case feelsLikeTemp = "#FEELS_LIKE_TEMP#"
case weatherType = "#WEATHER_TYPE#"
case weatherTypeChangeHour = "#WEATHER_TYPE_CHANGE_HOUR#"
func string(from location: Location) -> String {
func string(from location: Location) -> String? {
switch self {
case .feelsLikeTemp:
return location.today?.apparentTemp?.settingsConverted.shortString ?? "--"
case .weatherType:
guard let today = location.today else {
return nil
}
return today.type.localized(isDay: today.isDay)
case .weatherTypeChangeHour:
guard let today = location.today else {
return nil
}
let currentWeatherType = today.type
if let firstDifferentHour = location.hourly.first(where: { (hourly) -> Bool in
hourly.type != currentWeatherType
&& hourly.date > Date()
&& hourly.date < Date().addingTimeInterval(6 * 3600)
}) {
let dateFormatter = DateFormatter()
dateFormatter.timeZone = location.timeZone
dateFormatter.dateFormat = "h a"
return dateFormatter.string(from: firstDifferentHour.date)
}
else {
return nil
}
}
}
}
fileprivate let precipitationWeatherTypes = Set<WeatherType>([.snowy, .thunderstorm, .heavySnow, .lightSnow, .freezingRain, .lightHail, .lightDrizzle, .heavyRain])
fileprivate protocol SmartText {
var templateKey: String { get }
var requiredMacros: [Macro] { get }
func applicable(to: Location) -> Bool
func buildText(for location: Location) -> String
func applicable(to location: Location) -> Bool
func buildText(for location: Location) -> String?
}
fileprivate extension SmartText {
func buildText(for location: Location) -> String {
var result = self.templateKey.localized()
func buildText(for location: Location) -> String? {
var result: String? = self.templateKey.localized()
for macro in requiredMacros {
result = result.replacingOccurrences(of: macro.rawValue, with: macro.string(from: location))
if let macroValue = macro.string(from: location) {
result = result?.replacingOccurrences(of: macro.rawValue, with: macroValue)
}
else {
result = nil
break
}
}
return result
}
......@@ -38,22 +71,42 @@ fileprivate extension SmartText {
fileprivate struct DefaultSmartText: SmartText {
let templateKey = "today.smart.default"
var requiredMacros: [Macro] = [.feelsLikeTemp]
let requiredMacros: [Macro] = [.feelsLikeTemp]
func applicable(to: Location) -> Bool {
func applicable(to location: Location) -> Bool {
true
}
}
fileprivate struct OngoingPrecipitationSmartText: SmartText {
let templateKey: String = "today.smart.ongoingPrecipitation"
let requiredMacros: [Macro] = [.weatherType, .weatherTypeChangeHour]
func applicable(to location: Location) -> Bool {
guard let today = location.today else {
return false
}
return precipitationWeatherTypes.contains(today.type)
}
}
class SmartTextProvider {
private var prioritizedSmartTexts: [SmartText] = [DefaultSmartText()]
private var prioritizedSmartTexts: [SmartText] = [
OngoingPrecipitationSmartText(),
//Continue adding here.
DefaultSmartText()]
public func smartText(for location: Location) -> String {
var result = ""
for candidate in prioritizedSmartTexts {
if candidate.applicable(to: location) {
result = candidate.buildText(for: location)
break
if let candidateText = candidate.buildText(for: location) {
result = candidateText
break
}
}
}
return result
......
......@@ -36,7 +36,8 @@
"privacy.notice.close" = "Close";
//Today Smart Text
"today.smart.default" = "Feels like #FEELS_LIKE_TEMP.";
"today.smart.default" = "Feels like #FEELS_LIKE_TEMP#.";
"today.smart.ongoingPrecipitation" = "#WEATHER_TYPE# until #WEATHER_TYPE_CHANGE_HOUR#.";
//Forecast
"forecast.sunny" = "Sunny";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment