Commit a7dbecdb by Dmitriy Stepanets

Finished precipitation widget integration

parent 9b566df2
No preview for this file type
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
CD18728B2624763000AFEDAA /* MapLegendView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD18728A2624763000AFEDAA /* MapLegendView.swift */; }; CD18728B2624763000AFEDAA /* MapLegendView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD18728A2624763000AFEDAA /* MapLegendView.swift */; };
CD1B713B2660F95000916E71 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD1B713A2660F95000916E71 /* WidgetKit.framework */; }; CD1B713B2660F95000916E71 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD1B713A2660F95000916E71 /* WidgetKit.framework */; };
CD1B713D2660F95000916E71 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD1B713C2660F95000916E71 /* SwiftUI.framework */; }; CD1B713D2660F95000916E71 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD1B713C2660F95000916E71 /* SwiftUI.framework */; };
CD1B71402660F95000916E71 /* SmallTemperatureWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1B713F2660F95000916E71 /* SmallTemperatureWidget.swift */; }; CD1B71402660F95000916E71 /* TemperatureWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1B713F2660F95000916E71 /* TemperatureWidget.swift */; };
CD1B71462660F95300916E71 /* OneWeatherWidgetExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = CD1B71392660F95000916E71 /* OneWeatherWidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; CD1B71462660F95300916E71 /* OneWeatherWidgetExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = CD1B71392660F95000916E71 /* OneWeatherWidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
CD1DDD30260218AE00AC62B2 /* DaysControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1DDD2F260218AE00AC62B2 /* DaysControlView.swift */; }; CD1DDD30260218AE00AC62B2 /* DaysControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1DDD2F260218AE00AC62B2 /* DaysControlView.swift */; };
CD1DDD332602305200AC62B2 /* ForecastInfoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1DDD322602305200AC62B2 /* ForecastInfoCell.swift */; }; CD1DDD332602305200AC62B2 /* ForecastInfoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1DDD322602305200AC62B2 /* ForecastInfoCell.swift */; };
...@@ -88,6 +88,8 @@ ...@@ -88,6 +88,8 @@
CD55E0BB2615EE2400CC4DC7 /* PollutantView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD55E0BA2615EE2400CC4DC7 /* PollutantView.swift */; }; CD55E0BB2615EE2400CC4DC7 /* PollutantView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD55E0BA2615EE2400CC4DC7 /* PollutantView.swift */; };
CD5692B42653D46200A3CDBE /* SplashAnimationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5692B32653D46100A3CDBE /* SplashAnimationViewController.swift */; }; CD5692B42653D46200A3CDBE /* SplashAnimationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5692B32653D46100A3CDBE /* SplashAnimationViewController.swift */; };
CD5692B62653D56700A3CDBE /* splash.json in Resources */ = {isa = PBXBuildFile; fileRef = CD5692B52653D56700A3CDBE /* splash.json */; }; CD5692B62653D56700A3CDBE /* splash.json in Resources */ = {isa = PBXBuildFile; fileRef = CD5692B52653D56700A3CDBE /* splash.json */; };
CD58529026A01F0E00D61021 /* PrecipitationWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD58528F26A01F0E00D61021 /* PrecipitationWidget.swift */; };
CD58529226A02B3200D61021 /* PromotionWidgetViewWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD58529126A02B3100D61021 /* PromotionWidgetViewWrapper.swift */; };
CD593BC226088A5900C93428 /* TimePeriodOffsetHolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD593BC126088A5900C93428 /* TimePeriodOffsetHolder.swift */; }; CD593BC226088A5900C93428 /* TimePeriodOffsetHolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD593BC126088A5900C93428 /* TimePeriodOffsetHolder.swift */; };
CD593BCC2608A4F200C93428 /* ForecastDailyCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD593BCB2608A4F200C93428 /* ForecastDailyCell.swift */; }; CD593BCC2608A4F200C93428 /* ForecastDailyCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD593BCB2608A4F200C93428 /* ForecastDailyCell.swift */; };
CD593BCF2608A50900C93428 /* ForecastHourlyCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD593BCE2608A50900C93428 /* ForecastHourlyCell.swift */; }; CD593BCF2608A50900C93428 /* ForecastHourlyCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD593BCE2608A50900C93428 /* ForecastHourlyCell.swift */; };
...@@ -155,7 +157,6 @@ ...@@ -155,7 +157,6 @@
CDAC9B8526319B0500AC1BF4 /* MapTimeControlItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDAC9B8426319B0500AC1BF4 /* MapTimeControlItem.swift */; }; CDAC9B8526319B0500AC1BF4 /* MapTimeControlItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDAC9B8426319B0500AC1BF4 /* MapTimeControlItem.swift */; };
CDAD97B1262042B2007FCFB1 /* MapButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDAD97B0262042B2007FCFB1 /* MapButton.swift */; }; CDAD97B1262042B2007FCFB1 /* MapButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDAD97B0262042B2007FCFB1 /* MapButton.swift */; };
CDAD97B426207D14007FCFB1 /* MapTimeControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDAD97B326207D14007FCFB1 /* MapTimeControlView.swift */; }; CDAD97B426207D14007FCFB1 /* MapTimeControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDAD97B326207D14007FCFB1 /* MapTimeControlView.swift */; };
CDBF6D0A26988EAD00715981 /* LargeTemperatureWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDBF6D0926988EAD00715981 /* LargeTemperatureWidget.swift */; };
CDC3F858269460E600AAE3BF /* PromotionMediumWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC3F857269460E600AAE3BF /* PromotionMediumWidgetView.swift */; }; CDC3F858269460E600AAE3BF /* PromotionMediumWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC3F857269460E600AAE3BF /* PromotionMediumWidgetView.swift */; };
CDC6124F25E7964700188DA7 /* TodayDayTimesCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC6124E25E7964700188DA7 /* TodayDayTimesCell.swift */; }; CDC6124F25E7964700188DA7 /* TodayDayTimesCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC6124E25E7964700188DA7 /* TodayDayTimesCell.swift */; };
CDC6125325E79C8F00188DA7 /* DayTimeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC6125225E79C8F00188DA7 /* DayTimeView.swift */; }; CDC6125325E79C8F00188DA7 /* DayTimeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC6125225E79C8F00188DA7 /* DayTimeView.swift */; };
...@@ -208,7 +209,6 @@ ...@@ -208,7 +209,6 @@
CE578FE525FB415F00E8B85D /* CityCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE578FE225FB415F00E8B85D /* CityCell.swift */; }; CE578FE525FB415F00E8B85D /* CityCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE578FE225FB415F00E8B85D /* CityCell.swift */; };
CE578FE625FB415F00E8B85D /* LocationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE578FE325FB415F00E8B85D /* LocationViewController.swift */; }; CE578FE625FB415F00E8B85D /* LocationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE578FE325FB415F00E8B85D /* LocationViewController.swift */; };
CE578FE725FB415F00E8B85D /* LocationsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE578FE425FB415F00E8B85D /* LocationsViewModel.swift */; }; CE578FE725FB415F00E8B85D /* LocationsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE578FE425FB415F00E8B85D /* LocationsViewModel.swift */; };
CE5F0CBA268A02C100B99572 /* MediumTemperatureWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE5F0CB9268A02C100B99572 /* MediumTemperatureWidget.swift */; };
CE5F0CBC268A031800B99572 /* OneWeatherWidgetsBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE5F0CBB268A031800B99572 /* OneWeatherWidgetsBundle.swift */; }; CE5F0CBC268A031800B99572 /* OneWeatherWidgetsBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE5F0CBB268A031800B99572 /* OneWeatherWidgetsBundle.swift */; };
CE6BE4942634170800626822 /* USStateCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6BE4932634170800626822 /* USStateCode.swift */; }; CE6BE4942634170800626822 /* USStateCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6BE4932634170800626822 /* USStateCode.swift */; };
CE7298C9267A34F3002745D0 /* BlendFIPSSource.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEEF40FF265E47FF00425D8F /* BlendFIPSSource.framework */; }; CE7298C9267A34F3002745D0 /* BlendFIPSSource.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEEF40FF265E47FF00425D8F /* BlendFIPSSource.framework */; };
...@@ -349,7 +349,7 @@ ...@@ -349,7 +349,7 @@
CD1B71392660F95000916E71 /* OneWeatherWidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = OneWeatherWidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; CD1B71392660F95000916E71 /* OneWeatherWidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = OneWeatherWidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
CD1B713A2660F95000916E71 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; }; CD1B713A2660F95000916E71 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
CD1B713C2660F95000916E71 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; }; CD1B713C2660F95000916E71 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
CD1B713F2660F95000916E71 /* SmallTemperatureWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmallTemperatureWidget.swift; sourceTree = "<group>"; }; CD1B713F2660F95000916E71 /* TemperatureWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemperatureWidget.swift; sourceTree = "<group>"; };
CD1B71432660F95300916E71 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; CD1B71432660F95300916E71 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CD1DDD2F260218AE00AC62B2 /* DaysControlView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DaysControlView.swift; sourceTree = "<group>"; }; CD1DDD2F260218AE00AC62B2 /* DaysControlView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DaysControlView.swift; sourceTree = "<group>"; };
CD1DDD322602305200AC62B2 /* ForecastInfoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastInfoCell.swift; sourceTree = "<group>"; }; CD1DDD322602305200AC62B2 /* ForecastInfoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastInfoCell.swift; sourceTree = "<group>"; };
...@@ -388,12 +388,15 @@ ...@@ -388,12 +388,15 @@
CD483A992664DF7300CA53AB /* SF-Pro-Display-Light.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SF-Pro-Display-Light.otf"; sourceTree = "<group>"; }; CD483A992664DF7300CA53AB /* SF-Pro-Display-Light.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SF-Pro-Display-Light.otf"; sourceTree = "<group>"; };
CD483A9C2664E08200CA53AB /* SF-Pro-Display-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SF-Pro-Display-Regular.otf"; sourceTree = "<group>"; }; CD483A9C2664E08200CA53AB /* SF-Pro-Display-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SF-Pro-Display-Regular.otf"; sourceTree = "<group>"; };
CD50555E26983C14006776AB /* CubicCurveAlgorithm.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CubicCurveAlgorithm.swift; sourceTree = "<group>"; }; CD50555E26983C14006776AB /* CubicCurveAlgorithm.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CubicCurveAlgorithm.swift; sourceTree = "<group>"; };
CD5181BF269EEB61008E6B04 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; };
CD5293D7266908DB009547C8 /* WidgetPlaceholderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetPlaceholderView.swift; sourceTree = "<group>"; }; CD5293D7266908DB009547C8 /* WidgetPlaceholderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetPlaceholderView.swift; sourceTree = "<group>"; };
CD5293D92669094E009547C8 /* WeatherEntry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeatherEntry.swift; sourceTree = "<group>"; }; CD5293D92669094E009547C8 /* WeatherEntry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeatherEntry.swift; sourceTree = "<group>"; };
CD5293DE266A235F009547C8 /* ForecastWidgetViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastWidgetViewModel.swift; sourceTree = "<group>"; }; CD5293DE266A235F009547C8 /* ForecastWidgetViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastWidgetViewModel.swift; sourceTree = "<group>"; };
CD55E0BA2615EE2400CC4DC7 /* PollutantView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollutantView.swift; sourceTree = "<group>"; }; CD55E0BA2615EE2400CC4DC7 /* PollutantView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollutantView.swift; sourceTree = "<group>"; };
CD5692B32653D46100A3CDBE /* SplashAnimationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SplashAnimationViewController.swift; sourceTree = "<group>"; }; CD5692B32653D46100A3CDBE /* SplashAnimationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SplashAnimationViewController.swift; sourceTree = "<group>"; };
CD5692B52653D56700A3CDBE /* splash.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = splash.json; sourceTree = "<group>"; }; CD5692B52653D56700A3CDBE /* splash.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = splash.json; sourceTree = "<group>"; };
CD58528F26A01F0E00D61021 /* PrecipitationWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrecipitationWidget.swift; sourceTree = "<group>"; };
CD58529126A02B3100D61021 /* PromotionWidgetViewWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromotionWidgetViewWrapper.swift; sourceTree = "<group>"; };
CD593BC126088A5900C93428 /* TimePeriodOffsetHolder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimePeriodOffsetHolder.swift; sourceTree = "<group>"; }; CD593BC126088A5900C93428 /* TimePeriodOffsetHolder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimePeriodOffsetHolder.swift; sourceTree = "<group>"; };
CD593BCB2608A4F200C93428 /* ForecastDailyCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastDailyCell.swift; sourceTree = "<group>"; }; CD593BCB2608A4F200C93428 /* ForecastDailyCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastDailyCell.swift; sourceTree = "<group>"; };
CD593BCE2608A50900C93428 /* ForecastHourlyCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastHourlyCell.swift; sourceTree = "<group>"; }; CD593BCE2608A50900C93428 /* ForecastHourlyCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastHourlyCell.swift; sourceTree = "<group>"; };
...@@ -460,7 +463,6 @@ ...@@ -460,7 +463,6 @@
CDAC9B8426319B0500AC1BF4 /* MapTimeControlItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTimeControlItem.swift; sourceTree = "<group>"; }; CDAC9B8426319B0500AC1BF4 /* MapTimeControlItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTimeControlItem.swift; sourceTree = "<group>"; };
CDAD97B0262042B2007FCFB1 /* MapButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapButton.swift; sourceTree = "<group>"; }; CDAD97B0262042B2007FCFB1 /* MapButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapButton.swift; sourceTree = "<group>"; };
CDAD97B326207D14007FCFB1 /* MapTimeControlView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTimeControlView.swift; sourceTree = "<group>"; }; CDAD97B326207D14007FCFB1 /* MapTimeControlView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTimeControlView.swift; sourceTree = "<group>"; };
CDBF6D0926988EAD00715981 /* LargeTemperatureWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeTemperatureWidget.swift; sourceTree = "<group>"; };
CDC3F857269460E600AAE3BF /* PromotionMediumWidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromotionMediumWidgetView.swift; sourceTree = "<group>"; }; CDC3F857269460E600AAE3BF /* PromotionMediumWidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromotionMediumWidgetView.swift; sourceTree = "<group>"; };
CDC6124E25E7964700188DA7 /* TodayDayTimesCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayDayTimesCell.swift; sourceTree = "<group>"; }; CDC6124E25E7964700188DA7 /* TodayDayTimesCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayDayTimesCell.swift; sourceTree = "<group>"; };
CDC6125225E79C8F00188DA7 /* DayTimeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DayTimeView.swift; sourceTree = "<group>"; }; CDC6125225E79C8F00188DA7 /* DayTimeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DayTimeView.swift; sourceTree = "<group>"; };
...@@ -515,7 +517,6 @@ ...@@ -515,7 +517,6 @@
CE578FE325FB415F00E8B85D /* LocationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationViewController.swift; sourceTree = "<group>"; }; CE578FE325FB415F00E8B85D /* LocationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationViewController.swift; sourceTree = "<group>"; };
CE578FE425FB415F00E8B85D /* LocationsViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationsViewModel.swift; sourceTree = "<group>"; }; CE578FE425FB415F00E8B85D /* LocationsViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationsViewModel.swift; sourceTree = "<group>"; };
CE5F0CB7268A025C00B99572 /* MediumTemperatureWidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediumTemperatureWidgetView.swift; sourceTree = "<group>"; }; CE5F0CB7268A025C00B99572 /* MediumTemperatureWidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediumTemperatureWidgetView.swift; sourceTree = "<group>"; };
CE5F0CB9268A02C100B99572 /* MediumTemperatureWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediumTemperatureWidget.swift; sourceTree = "<group>"; };
CE5F0CBB268A031800B99572 /* OneWeatherWidgetsBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OneWeatherWidgetsBundle.swift; sourceTree = "<group>"; }; CE5F0CBB268A031800B99572 /* OneWeatherWidgetsBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OneWeatherWidgetsBundle.swift; sourceTree = "<group>"; };
CE6BE4932634170800626822 /* USStateCode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = USStateCode.swift; sourceTree = "<group>"; }; CE6BE4932634170800626822 /* USStateCode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = USStateCode.swift; sourceTree = "<group>"; };
CE81A421266E289E00800EFF /* NativeAdView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeAdView.swift; sourceTree = "<group>"; }; CE81A421266E289E00800EFF /* NativeAdView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeAdView.swift; sourceTree = "<group>"; };
...@@ -709,12 +710,12 @@ ...@@ -709,12 +710,12 @@
CD1B713E2660F95000916E71 /* OneWeatherWidget */ = { CD1B713E2660F95000916E71 /* OneWeatherWidget */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CE5F0CBB268A031800B99572 /* OneWeatherWidgetsBundle.swift */,
CD5293DD266A2345009547C8 /* ViewModels */, CD5293DD266A2345009547C8 /* ViewModels */,
CD5293DC266909B0009547C8 /* Data */, CD5293DC266909B0009547C8 /* Data */,
CD5293DB2669099B009547C8 /* UI */, CD5293DB2669099B009547C8 /* UI */,
CE5F0CBD268A058700B99572 /* Widgets */, CE5F0CBD268A058700B99572 /* Widgets */,
CD1B71432660F95300916E71 /* Info.plist */, CD1B71432660F95300916E71 /* Info.plist */,
CE5F0CBB268A031800B99572 /* OneWeatherWidgetsBundle.swift */,
); );
path = OneWeatherWidget; path = OneWeatherWidget;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -1003,6 +1004,7 @@ ...@@ -1003,6 +1004,7 @@
CD857EA6268B45DD00B5E069 /* PromotionSmallWidgetView.swift */, CD857EA6268B45DD00B5E069 /* PromotionSmallWidgetView.swift */,
CDC3F857269460E600AAE3BF /* PromotionMediumWidgetView.swift */, CDC3F857269460E600AAE3BF /* PromotionMediumWidgetView.swift */,
CD7EB377269C60680088999D /* PromotionLargeWidgetView.swift */, CD7EB377269C60680088999D /* PromotionLargeWidgetView.swift */,
CD58529126A02B3100D61021 /* PromotionWidgetViewWrapper.swift */,
); );
path = Views; path = Views;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -1304,9 +1306,8 @@ ...@@ -1304,9 +1306,8 @@
CE5F0CBD268A058700B99572 /* Widgets */ = { CE5F0CBD268A058700B99572 /* Widgets */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CD1B713F2660F95000916E71 /* SmallTemperatureWidget.swift */, CD1B713F2660F95000916E71 /* TemperatureWidget.swift */,
CE5F0CB9268A02C100B99572 /* MediumTemperatureWidget.swift */, CD58528F26A01F0E00D61021 /* PrecipitationWidget.swift */,
CDBF6D0926988EAD00715981 /* LargeTemperatureWidget.swift */,
); );
path = Widgets; path = Widgets;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -1389,6 +1390,7 @@ ...@@ -1389,6 +1390,7 @@
DBFD169AA2AA6A3CB5B68BB5 /* Frameworks */ = { DBFD169AA2AA6A3CB5B68BB5 /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CD5181BF269EEB61008E6B04 /* CoreLocation.framework */,
CD7D3183268F1438000D01FA /* OneWeatherUI.framework */, CD7D3183268F1438000D01FA /* OneWeatherUI.framework */,
CDEF70E2266E10B600BA40D6 /* OneWeatherCore.framework */, CDEF70E2266E10B600BA40D6 /* OneWeatherCore.framework */,
CE30E37E2668FBE3006DF5CD /* OneWeatherAnalytics.framework */, CE30E37E2668FBE3006DF5CD /* OneWeatherAnalytics.framework */,
...@@ -1803,6 +1805,7 @@ ...@@ -1803,6 +1805,7 @@
CD32CE0E260C770E00235081 /* MenuHeaderView.swift in Sources */, CD32CE0E260C770E00235081 /* MenuHeaderView.swift in Sources */,
CD15DB3D25DA6C5100024727 /* ForecastTimePeriodControl.swift in Sources */, CD15DB3D25DA6C5100024727 /* ForecastTimePeriodControl.swift in Sources */,
CD67617726259DD70079D273 /* MapLayersPresentationAnimator.swift in Sources */, CD67617726259DD70079D273 /* MapLayersPresentationAnimator.swift in Sources */,
CD58529226A02B3200D61021 /* PromotionWidgetViewWrapper.swift in Sources */,
CD3D567F268C705900DB99B6 /* PromotionPresentationAnimator.swift in Sources */, CD3D567F268C705900DB99B6 /* PromotionPresentationAnimator.swift in Sources */,
CD7BF1582620410800A30DF5 /* RadarCoordinator.swift in Sources */, CD7BF1582620410800A30DF5 /* RadarCoordinator.swift in Sources */,
CDD0F1EE25725BCF00CF5017 /* ThemeManager.swift in Sources */, CDD0F1EE25725BCF00CF5017 /* ThemeManager.swift in Sources */,
...@@ -1931,15 +1934,14 @@ ...@@ -1931,15 +1934,14 @@
files = ( files = (
CD5293E1266A4258009547C8 /* AppFont.swift in Sources */, CD5293E1266A4258009547C8 /* AppFont.swift in Sources */,
CD5293DF266A235F009547C8 /* ForecastWidgetViewModel.swift in Sources */, CD5293DF266A235F009547C8 /* ForecastWidgetViewModel.swift in Sources */,
CE5F0CBA268A02C100B99572 /* MediumTemperatureWidget.swift in Sources */,
CD5293D8266908DB009547C8 /* WidgetPlaceholderView.swift in Sources */, CD5293D8266908DB009547C8 /* WidgetPlaceholderView.swift in Sources */,
CDBF6D0A26988EAD00715981 /* LargeTemperatureWidget.swift in Sources */,
CD5293EA266A564E009547C8 /* ThemeProtocol.swift in Sources */, CD5293EA266A564E009547C8 /* ThemeProtocol.swift in Sources */,
CD1B71402660F95000916E71 /* SmallTemperatureWidget.swift in Sources */, CD1B71402660F95000916E71 /* TemperatureWidget.swift in Sources */,
CD5293E8266A561F009547C8 /* DefaultTheme.swift in Sources */, CD5293E8266A561F009547C8 /* DefaultTheme.swift in Sources */,
CD5293E7266A560C009547C8 /* ThemeManager.swift in Sources */, CD5293E7266A560C009547C8 /* ThemeManager.swift in Sources */,
CE5F0CBC268A031800B99572 /* OneWeatherWidgetsBundle.swift in Sources */, CE5F0CBC268A031800B99572 /* OneWeatherWidgetsBundle.swift in Sources */,
CD415DA32668FFF300177515 /* WeatherProvider.swift in Sources */, CD415DA32668FFF300177515 /* WeatherProvider.swift in Sources */,
CD58529026A01F0E00D61021 /* PrecipitationWidget.swift in Sources */,
CD5293DA2669094E009547C8 /* WeatherEntry.swift in Sources */, CD5293DA2669094E009547C8 /* WeatherEntry.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
......
...@@ -80,7 +80,7 @@ ...@@ -80,7 +80,7 @@
<EnvironmentVariables> <EnvironmentVariables>
<EnvironmentVariable <EnvironmentVariable
key = "_XCWidgetKind" key = "_XCWidgetKind"
value = "com.onelouder.oneweather.widget.medium.temperature" value = "com.onelouder.oneweather.widget.temperature"
isEnabled = "YES"> isEnabled = "YES">
</EnvironmentVariable> </EnvironmentVariable>
<EnvironmentVariable <EnvironmentVariable
......
...@@ -285,10 +285,8 @@ ...@@ -285,10 +285,8 @@
"widget.promotion.learn" = "Learn to add widget"; "widget.promotion.learn" = "Learn to add widget";
//Widget //Widget
"widget.small.title" = "Temperature Forecast"; "widget.temperature.title" = "Temperature Forecast";
"widget.small.description" = ""; "widget.temperature.description" = "";
"widget.medium.title" = "Temperature Forecast"; "widget.precipitation.title" = "Precipitation Forecast";
"widget.medium.description" = ""; "widget.precipitation.description" = "";
"widget.large.title" = "Temperature Forecast";
"widget.large.description" = "";
"widget.lastUpdatedTemplate" = "Last updated #LAST_UPDATED ago."; "widget.lastUpdatedTemplate" = "Last updated #LAST_UPDATED ago.";
//
// PromotionWidgetViewWrapper.swift
// 1Weather
//
// Created by Dmitry Stepanets on 15.07.2021.
//
import UIKit
import SwiftUI
import OneWeatherUI
@available(iOS 14, *)
enum PromotionWidgetType {
case temperatureSmall
case temperatureMedium
case temperatureLarge
case precipitationMedium
var widgetHeight: Int {
switch self {
case .temperatureLarge:
return 376
default:
return 169
}
}
}
@available(iOS 14, *)
class PromotionWidgetViewWrapper: UIView {
private let widgetController: UIViewController
private let widgetType: PromotionWidgetType
init(widgetType: PromotionWidgetType) {
switch widgetType {
case .temperatureSmall:
widgetController = UIHostingController(rootView: SmallTemperatureWidgetView(widgetViewModel: nil))
case .temperatureMedium:
widgetController = UIHostingController(rootView: MediumTemperatureWidgetView(widgetViewModel: nil))
case .temperatureLarge:
widgetController = UIHostingController(rootView: LargeTemperatureWidgetView(widgetViewModel: nil))
case .precipitationMedium:
widgetController = UIHostingController(rootView: MediumPrecipitationWidgetView(widgetViewModel: nil))
}
self.widgetType = widgetType
super.init(frame: .zero)
prepareWidgetView()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//MARK:- Prepare
@available(iOS 14, *)
private extension PromotionWidgetViewWrapper {
func prepareWidgetView() {
let container = UIView()
container.addSubview(widgetController.view)
container.clipsToBounds = true
container.layer.cornerRadius = 20
addSubview(container)
widgetController.view.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
container.snp.makeConstraints { make in
make.height.equalTo(widgetType.widgetHeight)
make.left.right.equalToSuperview().inset(18)
make.top.equalToSuperview().inset(20)
make.bottom.equalToSuperview()
}
}
}
...@@ -169,7 +169,7 @@ private extension WidgetPromotionController { ...@@ -169,7 +169,7 @@ private extension WidgetPromotionController {
scrollView.snp.makeConstraints { make in scrollView.snp.makeConstraints { make in
make.left.right.equalToSuperview() make.left.right.equalToSuperview()
make.top.equalToSuperview().inset(kScrollViewTopInset) make.top.equalToSuperview().inset(kScrollViewTopInset)
make.bottom.equalTo(footerView.snp.top).offset(4) make.bottom.equalTo(footerView.snp.top).offset(8)
} }
} }
...@@ -179,8 +179,8 @@ private extension WidgetPromotionController { ...@@ -179,8 +179,8 @@ private extension WidgetPromotionController {
stackView.spacing = 0 stackView.spacing = 0
stackView.addArrangedSubview(PromotionHeaderView()) stackView.addArrangedSubview(PromotionHeaderView())
stackView.addArrangedSubview(PromotionSmallWidgetView()) stackView.addArrangedSubview(PromotionSmallWidgetView())
stackView.addArrangedSubview(PromotionMediumWidgetView()) stackView.addArrangedSubview(PromotionWidgetViewWrapper(widgetType: .temperatureMedium))
stackView.addArrangedSubview(PromotionLargeWidgetView()) stackView.addArrangedSubview(PromotionWidgetViewWrapper(widgetType: .precipitationMedium))
scrollView.addSubview(stackView) scrollView.addSubview(stackView)
stackView.snp.makeConstraints { make in stackView.snp.makeConstraints { make in
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
CD2E07BF269C5834001CBF40 /* SF-Pro-Display-Thin.otf in Resources */ = {isa = PBXBuildFile; fileRef = CD2E07BE269C5834001CBF40 /* SF-Pro-Display-Thin.otf */; }; CD2E07BF269C5834001CBF40 /* SF-Pro-Display-Thin.otf in Resources */ = {isa = PBXBuildFile; fileRef = CD2E07BE269C5834001CBF40 /* SF-Pro-Display-Thin.otf */; };
CD2E07C1269C5ABF001CBF40 /* HourlyTemperatureView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD2E07C0269C5ABF001CBF40 /* HourlyTemperatureView.swift */; }; CD2E07C1269C5ABF001CBF40 /* HourlyTemperatureView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD2E07C0269C5ABF001CBF40 /* HourlyTemperatureView.swift */; };
CD3C83C326933ABD0087A225 /* MediumTemperatureWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD3C83C226933ABC0087A225 /* MediumTemperatureWidgetView.swift */; }; CD3C83C326933ABD0087A225 /* MediumTemperatureWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD3C83C226933ABC0087A225 /* MediumTemperatureWidgetView.swift */; };
CD4319FA26A00E090019A232 /* MediumWidgetTopView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD4319F926A00E090019A232 /* MediumWidgetTopView.swift */; };
CD4319FC26A014CF0019A232 /* MediumPrecipitationWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD4319FB26A014CF0019A232 /* MediumPrecipitationWidgetView.swift */; };
CD50556126983C2F006776AB /* CubicCurveAlgorithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD50556026983C2E006776AB /* CubicCurveAlgorithm.swift */; }; CD50556126983C2F006776AB /* CubicCurveAlgorithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD50556026983C2E006776AB /* CubicCurveAlgorithm.swift */; };
CD7D3161268EEF49000D01FA /* CityNameView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD7D315F268EEF48000D01FA /* CityNameView.swift */; }; CD7D3161268EEF49000D01FA /* CityNameView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD7D315F268EEF48000D01FA /* CityNameView.swift */; };
CD7D3162268EEF49000D01FA /* HighLowTemperatureView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD7D3160268EEF49000D01FA /* HighLowTemperatureView.swift */; }; CD7D3162268EEF49000D01FA /* HighLowTemperatureView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD7D3160268EEF49000D01FA /* HighLowTemperatureView.swift */; };
...@@ -36,7 +38,6 @@ ...@@ -36,7 +38,6 @@
CDBF6D08269887A800715981 /* LargeTemperatureWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDBF6D07269887A800715981 /* LargeTemperatureWidgetView.swift */; }; CDBF6D08269887A800715981 /* LargeTemperatureWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDBF6D07269887A800715981 /* LargeTemperatureWidgetView.swift */; };
CDC3F85A26946D0700AAE3BF /* HourlyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC3F85926946D0700AAE3BF /* HourlyView.swift */; }; CDC3F85A26946D0700AAE3BF /* HourlyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC3F85926946D0700AAE3BF /* HourlyView.swift */; };
CDC3F85C269471C900AAE3BF /* SF-Pro-Display-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = CDC3F85B269471C900AAE3BF /* SF-Pro-Display-Bold.otf */; }; CDC3F85C269471C900AAE3BF /* SF-Pro-Display-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = CDC3F85B269471C900AAE3BF /* SF-Pro-Display-Bold.otf */; };
CDE43FD62695C65700DBE79E /* HourlyTemps.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDE43FD52695C65700DBE79E /* HourlyTemps.swift */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
...@@ -66,6 +67,8 @@ ...@@ -66,6 +67,8 @@
CD2E07BE269C5834001CBF40 /* SF-Pro-Display-Thin.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SF-Pro-Display-Thin.otf"; sourceTree = "<group>"; }; CD2E07BE269C5834001CBF40 /* SF-Pro-Display-Thin.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SF-Pro-Display-Thin.otf"; sourceTree = "<group>"; };
CD2E07C0269C5ABF001CBF40 /* HourlyTemperatureView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HourlyTemperatureView.swift; sourceTree = "<group>"; }; CD2E07C0269C5ABF001CBF40 /* HourlyTemperatureView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HourlyTemperatureView.swift; sourceTree = "<group>"; };
CD3C83C226933ABC0087A225 /* MediumTemperatureWidgetView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediumTemperatureWidgetView.swift; sourceTree = "<group>"; }; CD3C83C226933ABC0087A225 /* MediumTemperatureWidgetView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediumTemperatureWidgetView.swift; sourceTree = "<group>"; };
CD4319F926A00E090019A232 /* MediumWidgetTopView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediumWidgetTopView.swift; sourceTree = "<group>"; };
CD4319FB26A014CF0019A232 /* MediumPrecipitationWidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediumPrecipitationWidgetView.swift; sourceTree = "<group>"; };
CD50556026983C2E006776AB /* CubicCurveAlgorithm.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CubicCurveAlgorithm.swift; sourceTree = "<group>"; }; CD50556026983C2E006776AB /* CubicCurveAlgorithm.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CubicCurveAlgorithm.swift; sourceTree = "<group>"; };
CD6F063D269854A7002A99C2 /* BezierKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = BezierKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; CD6F063D269854A7002A99C2 /* BezierKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = BezierKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
CD7D315F268EEF48000D01FA /* CityNameView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CityNameView.swift; sourceTree = "<group>"; }; CD7D315F268EEF48000D01FA /* CityNameView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CityNameView.swift; sourceTree = "<group>"; };
...@@ -87,7 +90,6 @@ ...@@ -87,7 +90,6 @@
CDBF6D07269887A800715981 /* LargeTemperatureWidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeTemperatureWidgetView.swift; sourceTree = "<group>"; }; CDBF6D07269887A800715981 /* LargeTemperatureWidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeTemperatureWidgetView.swift; sourceTree = "<group>"; };
CDC3F85926946D0700AAE3BF /* HourlyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HourlyView.swift; sourceTree = "<group>"; }; CDC3F85926946D0700AAE3BF /* HourlyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HourlyView.swift; sourceTree = "<group>"; };
CDC3F85B269471C900AAE3BF /* SF-Pro-Display-Bold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SF-Pro-Display-Bold.otf"; sourceTree = "<group>"; }; CDC3F85B269471C900AAE3BF /* SF-Pro-Display-Bold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SF-Pro-Display-Bold.otf"; sourceTree = "<group>"; };
CDE43FD52695C65700DBE79E /* HourlyTemps.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HourlyTemps.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
...@@ -176,15 +178,31 @@ ...@@ -176,15 +178,31 @@
CD259C12268DE1F7008D205E /* Widgets */ = { CD259C12268DE1F7008D205E /* Widgets */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CD4319F826A00DB70019A232 /* Precipitation */,
CD4319F726A00DAB0019A232 /* Temperature */,
CDF2CF7026982DD6005EF42E /* Helpers */, CDF2CF7026982DD6005EF42E /* Helpers */,
CD1BF3B02698238A00F60E2E /* ViewModels */, CD1BF3B02698238A00F60E2E /* ViewModels */,
CDE43FD52695C65700DBE79E /* HourlyTemps.swift */, CD7D315E268EEF37000D01FA /* SharedViews */,
);
path = Widgets;
sourceTree = "<group>";
};
CD4319F726A00DAB0019A232 /* Temperature */ = {
isa = PBXGroup;
children = (
CD7D3163268EEF56000D01FA /* SmallTemperatureWidgetView.swift */, CD7D3163268EEF56000D01FA /* SmallTemperatureWidgetView.swift */,
CD3C83C226933ABC0087A225 /* MediumTemperatureWidgetView.swift */, CD3C83C226933ABC0087A225 /* MediumTemperatureWidgetView.swift */,
CDBF6D07269887A800715981 /* LargeTemperatureWidgetView.swift */, CDBF6D07269887A800715981 /* LargeTemperatureWidgetView.swift */,
CD7D315E268EEF37000D01FA /* SharedViews */,
); );
path = Widgets; path = Temperature;
sourceTree = "<group>";
};
CD4319F826A00DB70019A232 /* Precipitation */ = {
isa = PBXGroup;
children = (
CD4319FB26A014CF0019A232 /* MediumPrecipitationWidgetView.swift */,
);
path = Precipitation;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
CD7D315E268EEF37000D01FA /* SharedViews */ = { CD7D315E268EEF37000D01FA /* SharedViews */ = {
...@@ -195,6 +213,7 @@ ...@@ -195,6 +213,7 @@
CDC3F85926946D0700AAE3BF /* HourlyView.swift */, CDC3F85926946D0700AAE3BF /* HourlyView.swift */,
CD1BF3AE26981B5300F60E2E /* TemperatureGraphView.swift */, CD1BF3AE26981B5300F60E2E /* TemperatureGraphView.swift */,
CD2E07C0269C5ABF001CBF40 /* HourlyTemperatureView.swift */, CD2E07C0269C5ABF001CBF40 /* HourlyTemperatureView.swift */,
CD4319F926A00E090019A232 /* MediumWidgetTopView.swift */,
); );
path = SharedViews; path = SharedViews;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -363,6 +382,7 @@ ...@@ -363,6 +382,7 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
CD4319FC26A014CF0019A232 /* MediumPrecipitationWidgetView.swift in Sources */,
CD1BF3AF26981B5300F60E2E /* TemperatureGraphView.swift in Sources */, CD1BF3AF26981B5300F60E2E /* TemperatureGraphView.swift in Sources */,
CD7D3162268EEF49000D01FA /* HighLowTemperatureView.swift in Sources */, CD7D3162268EEF49000D01FA /* HighLowTemperatureView.swift in Sources */,
CD2E07C1269C5ABF001CBF40 /* HourlyTemperatureView.swift in Sources */, CD2E07C1269C5ABF001CBF40 /* HourlyTemperatureView.swift in Sources */,
...@@ -374,8 +394,8 @@ ...@@ -374,8 +394,8 @@
CD7D3187268F1F2E000D01FA /* UIImage+Resize.swift in Sources */, CD7D3187268F1F2E000D01FA /* UIImage+Resize.swift in Sources */,
CD1BF3B2269823BA00F60E2E /* GraphViewModel.swift in Sources */, CD1BF3B2269823BA00F60E2E /* GraphViewModel.swift in Sources */,
CD50556126983C2F006776AB /* CubicCurveAlgorithm.swift in Sources */, CD50556126983C2F006776AB /* CubicCurveAlgorithm.swift in Sources */,
CD4319FA26A00E090019A232 /* MediumWidgetTopView.swift in Sources */,
CD7D3178268EFB9E000D01FA /* WidgetViewModelMock.swift in Sources */, CD7D3178268EFB9E000D01FA /* WidgetViewModelMock.swift in Sources */,
CDE43FD62695C65700DBE79E /* HourlyTemps.swift in Sources */,
CD7D316F268EF2BC000D01FA /* WidgetViewModel.swift in Sources */, CD7D316F268EF2BC000D01FA /* WidgetViewModel.swift in Sources */,
CD7D3182268F0C60000D01FA /* OneWeatherUI+Global.swift in Sources */, CD7D3182268F0C60000D01FA /* OneWeatherUI+Global.swift in Sources */,
CDBF6D08269887A800715981 /* LargeTemperatureWidgetView.swift in Sources */, CDBF6D08269887A800715981 /* LargeTemperatureWidgetView.swift in Sources */,
......
{
"images" : [
{
"filename" : "precipitation_full.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}
{
"images" : [
{
"filename" : "precipitation_zero.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}
//
// MediumPrecipitationWidgetView.swift
// OneWeatherUI
//
// Created by Dmitry Stepanets on 15.07.2021.
//
import SwiftUI
@available(iOS 14, *)
public struct MediumPrecipitationWidgetView: View {
let widgetViewModel: WidgetViewModel
public init(widgetViewModel: WidgetViewModel?) {
OneWeatherUI.loadFonts
self.widgetViewModel = widgetViewModel ?? WidgetViewModelMock()
}
public var body: some View {
VStack(alignment: .center) {
MediumWidgetTopView(widgetViewModel: widgetViewModel)
.padding(.top, 12)
HStack(spacing: 10) {
ForEach(0 ..< widgetViewModel.hourlyWeather.count) { index in
HourlyView(hourlyWeather: widgetViewModel.hourlyWeather[index],
viewType: .precipitation)
.frame(maxWidth: 70)
}
}
.padding(.bottom, 10)
}
.padding([.leading, .trailing], 10)
.background(WidgetColor.Name("PrimaryBackground"))
}
}
@available(iOS 14, *)
struct MediumPrecipitationWidgetView_Preview: PreviewProvider {
public static var previews: some View {
MediumPrecipitationWidgetView(widgetViewModel: WidgetViewModelMock())
.previewDevice("iPhone 11")
.preferredColorScheme(.dark)
.frame(width: 338, height: 158)
}
}
...@@ -20,7 +20,7 @@ struct HourlyTemperatureView: View { ...@@ -20,7 +20,7 @@ struct HourlyTemperatureView: View {
ZStack { ZStack {
HStack(spacing: 10) { HStack(spacing: 10) {
ForEach(0 ..< hourlyWeather.count) { index in ForEach(0 ..< hourlyWeather.count) { index in
HourlyView(hourlyWeather: hourlyWeather[index]) HourlyView(hourlyWeather: hourlyWeather[index], viewType: .temperature)
.frame(maxWidth: 70) .frame(maxWidth: 70)
} }
} }
...@@ -28,7 +28,6 @@ struct HourlyTemperatureView: View { ...@@ -28,7 +28,6 @@ struct HourlyTemperatureView: View {
GeometryReader { geoInner in GeometryReader { geoInner in
Color(.clear) Color(.clear)
.onAppear { .onAppear {
print("[Widget] \(geoInner.frame(in: .global))")
hourlyStackFrame = hourlyWeather.isEmpty ? .zero : geoInner.frame(in: .global) hourlyStackFrame = hourlyWeather.isEmpty ? .zero : geoInner.frame(in: .global)
} }
} }
......
...@@ -8,23 +8,35 @@ ...@@ -8,23 +8,35 @@
import SwiftUI import SwiftUI
@available(iOS 14, *) @available(iOS 14, *)
enum HourlyViewType {
case temperature
case precipitation
}
@available(iOS 14, *)
struct HourlyView: View { struct HourlyView: View {
//Private //Private
@Environment(\.colorScheme) private var colorScheme @Environment(\.colorScheme) private var colorScheme
private let hourlyWeather: WidgetHourlyWeather private let hourlyWeather: WidgetHourlyWeather
private let viewType: HourlyViewType
public init(hourlyWeather: WidgetHourlyWeather) { public init(hourlyWeather: WidgetHourlyWeather, viewType: HourlyViewType) {
self.hourlyWeather = hourlyWeather self.hourlyWeather = hourlyWeather
self.viewType = viewType
} }
var body: some View { var body: some View {
VStack { VStack {
Text(hourlyWeather.tempLocalized) Text(viewType == .temperature ? hourlyWeather.tempLocalized : "\(hourlyWeather.precipitationPercent)%")
.foregroundColor(WidgetColor.Name("HourlyText")) .foregroundColor(WidgetColor.Name("HourlyText"))
.font(hourlyWeather.isSelected ? WidgetFont.SFProDisplay.bold(size: 16).font .font(hourlyWeather.isSelected ? WidgetFont.SFProDisplay.bold(size: 16).font
: WidgetFont.SFProDisplay.regular(size: 16).font) : WidgetFont.SFProDisplay.regular(size: 16).font)
.padding(.top, 8) .padding(.top, 8)
Spacer() Spacer()
if viewType == .precipitation {
precipitationImage()
Spacer()
}
Text(hourlyWeather.dateString) Text(hourlyWeather.dateString)
.foregroundColor(WidgetColor.Name("HourlyText")) .foregroundColor(WidgetColor.Name("HourlyText"))
.font(hourlyWeather.isSelected ? WidgetFont.SFProDisplay.bold(size: 12).font .font(hourlyWeather.isSelected ? WidgetFont.SFProDisplay.bold(size: 12).font
...@@ -36,9 +48,18 @@ struct HourlyView: View { ...@@ -36,9 +48,18 @@ struct HourlyView: View {
.compositingGroup() .compositingGroup()
.cornerRadius(12) .cornerRadius(12)
.modifier(Shadow(isSelected: hourlyWeather.isSelected)) .modifier(Shadow(isSelected: hourlyWeather.isSelected))
.opacity(hourlyWeather.isSelected ? 1 : 0.7)
.modifier(Border(isSelected: hourlyWeather.isSelected)) .modifier(Border(isSelected: hourlyWeather.isSelected))
} }
@available(iOS 14, *)
private func precipitationImage() -> Image {
let imageName = hourlyWeather.precipitationPercent > 0 ? "precipitation_full" : "precipitation_zero"
guard let uiImage = UIImage(named: imageName, in: OneWeatherUI.frameworkBundle, compatibleWith: nil) else {
return Image("")
}
return Image(uiImage: uiImage.scalePreservingAspectRatio(targetSize: .init(width: 18, height: 18)))
}
} }
@available(iOS 14, *) @available(iOS 14, *)
......
// //
// MediumTemperatureWidgetView.swift // MediumWidgetTopView.swift
// OneWeatherWidgetExtension // OneWeatherUI
// //
// Created by Demid Merzlyakov on 28.06.2021. // Created by Dmitry Stepanets on 15.07.2021.
// //
import SwiftUI import SwiftUI
import WidgetKit
@available (iOS 14, *) @available(iOS 14, *)
public struct MediumTemperatureWidgetView: View { struct MediumWidgetTopView: View {
//Public
let widgetViewModel: WidgetViewModel let widgetViewModel: WidgetViewModel
public init(widgetViewModel: WidgetViewModel?) { var body: some View {
OneWeatherUI.loadFonts VStack(spacing: 4) {
self.widgetViewModel = widgetViewModel ?? WidgetViewModelMock() HStack {
} HStack(spacing: 8) {
Text(widgetViewModel.temperature)
//Private .font(WidgetFont.SFProDisplay.light(size: 32).font)
@Environment(\.colorScheme) private var colorScheme .foregroundColor(WidgetColor.Name("PrimaryTextColor"))
Divider()
public var body: some View { .padding(.top, 8)
GeometryReader { geometry in .padding(.bottom, 8)
VStack(alignment: .leading) {
HStack {
HStack(spacing: 8) {
Text(widgetViewModel.temperature)
.font(WidgetFont.SFProDisplay.light(size: 32).font)
.foregroundColor(WidgetColor.Name("PrimaryTextColor"))
Divider()
.padding(.top, 8)
.padding(.bottom, 8)
Text(widgetViewModel.weatherType)
.font(WidgetFont.SFProDisplay.regular(size: 12).font)
.foregroundColor(WidgetColor.Name("PrimaryTextColor"))
.lineLimit(2)
weatherImage(uiImage: widgetViewModel.weatherIcon)
.aspectRatio(contentMode: .fit)
.frame(width: 30, height: 30, alignment: .center)
.shadow(for: colorScheme)
.padding(.trailing, 4)
}
Spacer()
VStack (spacing: 2) {
CityNameView(cityName: widgetViewModel.cityName, isDeviceLocation: widgetViewModel.isDeviceLocation)
HighLowTemperatureView(highTemperature: widgetViewModel.highTemperature, lowTemperature: widgetViewModel.lowTemperature)
}
.frame(height: 35)
} Text(widgetViewModel.weatherType)
.frame(height: 35)
.padding(.top, 12)
HStack(alignment: .top) {
Text(widgetViewModel.smartText)
.font(WidgetFont.SFProDisplay.regular(size: 12).font) .font(WidgetFont.SFProDisplay.regular(size: 12).font)
Spacer() .foregroundColor(WidgetColor.Name("PrimaryTextColor"))
.lineLimit(2)
if widgetViewModel.showLastTimeUpdated { weatherImage(uiImage: widgetViewModel.weatherIcon)
Text(widgetViewModel.lastTimeUpdatedText) .aspectRatio(contentMode: .fit)
.font(WidgetFont.SFProDisplay.regular(size: 9).font) .frame(width: 30, height: 30, alignment: .center)
} .modifier(Shadow())
.padding(.trailing, 4)
}
Spacer()
VStack (spacing: 2) {
CityNameView(cityName: widgetViewModel.cityName,
isDeviceLocation: widgetViewModel.isDeviceLocation)
HighLowTemperatureView(highTemperature: widgetViewModel.highTemperature,
lowTemperature: widgetViewModel.lowTemperature)
} }
.frame(height: 35)
HourlyTemperatureView(hourlyWeather: widgetViewModel.hourlyWeather)
} }
.padding([.leading, .trailing], 10) .frame(height: 35)
.background(WidgetColor.Name("PrimaryBackground"))
HStack(alignment: .top) {
Text(widgetViewModel.smartText)
.lineLimit(2)
.font(WidgetFont.SFProDisplay.regular(size: 12).font)
Spacer()
if widgetViewModel.showLastTimeUpdated {
Text(widgetViewModel.lastTimeUpdatedText)
.font(WidgetFont.SFProDisplay.regular(size: 9).font)
}
}
} }
} }
@available(iOS 14, *)
private func weatherImage(uiImage: UIImage) -> Image {
return Image(uiImage: uiImage.scalePreservingAspectRatio(targetSize: .init(width: 30, height: 30)))
}
} }
@available(iOS 14, *) @available(iOS 14, *)
private extension View { private struct Shadow: ViewModifier {
func shadow(for colorScheme: ColorScheme) -> some View { @Environment(\.colorScheme) private var colorScheme
func body(content: Content) -> some View {
switch colorScheme { switch colorScheme {
case .light: case .light:
return self.shadow(color: Color.black.opacity(0.5), radius: 16, x: 2, y: 0) content.shadow(color: Color.black.opacity(0.5), radius: 16, x: 2, y: 0)
case .dark: case .dark:
return self.shadow(color: Color.white.opacity(0.24), radius: 16, x: 2, y: 0) content.shadow(color: Color.white.opacity(0.24), radius: 16, x: 2, y: 0)
@unknown default: default:
return self.shadow(color: Color.black.opacity(0.5), radius: 16, x: 2, y: 0) fatalError("[OneWeatherUI] Unsopported color scheme")
} }
} }
func weatherImage(uiImage: UIImage) -> Image {
return Image(uiImage: uiImage.scalePreservingAspectRatio(targetSize: .init(width: 30, height: 30)))
}
} }
@available(iOS 14, *) @available(iOS 14, *)
public struct MediumTemperatureWidgetView_Preview: PreviewProvider { public struct MediumWidgetTopView_Preview: PreviewProvider {
public static var previews: some View { public static var previews: some View {
MediumTemperatureWidgetView(widgetViewModel: WidgetViewModelMock()) MediumWidgetTopView(widgetViewModel: WidgetViewModelMock())
.previewDevice("iPhone 11") .previewDevice("iPhone 11")
.preferredColorScheme(.light) .preferredColorScheme(.dark)
.background(WidgetColor.Name("PrimaryBackground"))
.frame(width: 338, height: 158) .frame(width: 338, height: 158)
} }
} }
...@@ -54,8 +54,8 @@ struct TemperatureGraphView: View { ...@@ -54,8 +54,8 @@ struct TemperatureGraphView: View {
Circle() Circle()
.overlay( .overlay(
Circle() Circle()
.stroke(hourlyWeather[index].isSelected ? WidgetColor.Name("GraphLineTint") .stroke(index == 0 ? WidgetColor.Name("GraphLineTint")
: WidgetColor.Name("GraphLine"), : WidgetColor.Name("GraphLine"),
lineWidth: 2) lineWidth: 2)
) )
.frame(width: 5, height: 5) .frame(width: 5, height: 5)
......
//
// MediumTemperatureWidgetView.swift
// OneWeatherWidgetExtension
//
// Created by Demid Merzlyakov on 28.06.2021.
//
import SwiftUI
import WidgetKit
@available (iOS 14, *)
public struct MediumTemperatureWidgetView: View {
//Public
let widgetViewModel: WidgetViewModel
public init(widgetViewModel: WidgetViewModel?) {
OneWeatherUI.loadFonts
self.widgetViewModel = widgetViewModel ?? WidgetViewModelMock()
}
public var body: some View {
VStack(alignment: .leading) {
MediumWidgetTopView(widgetViewModel: widgetViewModel)
.padding(.top, 10)
HourlyTemperatureView(hourlyWeather: widgetViewModel.hourlyWeather)
.padding(.bottom, 10)
}
.padding([.leading, .trailing], 10)
.background(WidgetColor.Name("PrimaryBackground"))
}
}
@available(iOS 14, *)
public struct MediumTemperatureWidgetView_Preview: PreviewProvider {
public static var previews: some View {
MediumTemperatureWidgetView(widgetViewModel: WidgetViewModelMock())
.previewDevice("iPhone 11")
.preferredColorScheme(.dark)
.frame(width: 338, height: 158)
}
}
...@@ -28,7 +28,7 @@ public struct SmallTemperatureWidgetView: View { ...@@ -28,7 +28,7 @@ public struct SmallTemperatureWidgetView: View {
isDeviceLocation: widgetViewModel.isDeviceLocation) isDeviceLocation: widgetViewModel.isDeviceLocation)
Spacer() Spacer()
} }
.padding(.top, 12) .padding(.top, 8)
.padding(.leading, 10) .padding(.leading, 10)
HStack(spacing: 0) { HStack(spacing: 0) {
...@@ -62,6 +62,7 @@ public struct SmallTemperatureWidgetView: View { ...@@ -62,6 +62,7 @@ public struct SmallTemperatureWidgetView: View {
.padding(.bottom, 21) .padding(.bottom, 21)
.padding(.leading, 10) .padding(.leading, 10)
} }
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(WidgetColor.Name("PrimaryBackground")) .background(WidgetColor.Name("PrimaryBackground"))
} }
} }
......
...@@ -16,9 +16,10 @@ public struct WidgetHourlyWeather { ...@@ -16,9 +16,10 @@ public struct WidgetHourlyWeather {
let windSpeedLocalized: String let windSpeedLocalized: String
let windDirection: String let windDirection: String
let windDegrees: CGFloat let windDegrees: CGFloat
let precipitationPercent: Int
let isSelected: Bool let isSelected: Bool
public init(dateString: String, temp: Double, tempLocalized: String, windSpeed: Double, windSpeedLocalized: String, windDirection: String, windDegrees: CGFloat, isSelected: Bool) { public init(dateString: String, temp: Double, tempLocalized: String, windSpeed: Double, windSpeedLocalized: String, windDirection: String, windDegrees: CGFloat, precipitationPercent: Int, isSelected: Bool) {
self.dateString = dateString self.dateString = dateString
self.temp = temp self.temp = temp
self.tempLocalized = tempLocalized self.tempLocalized = tempLocalized
...@@ -26,6 +27,7 @@ public struct WidgetHourlyWeather { ...@@ -26,6 +27,7 @@ public struct WidgetHourlyWeather {
self.windSpeedLocalized = windSpeedLocalized self.windSpeedLocalized = windSpeedLocalized
self.windDirection = windDirection self.windDirection = windDirection
self.windDegrees = windDegrees self.windDegrees = windDegrees
self.precipitationPercent = precipitationPercent
self.isSelected = isSelected self.isSelected = isSelected
} }
} }
......
...@@ -31,6 +31,7 @@ struct WidgetViewModelMock: WidgetViewModel { ...@@ -31,6 +31,7 @@ struct WidgetViewModelMock: WidgetViewModel {
windSpeedLocalized: "8m/s", windSpeedLocalized: "8m/s",
windDirection: "SSE", windDirection: "SSE",
windDegrees: 25, windDegrees: 25,
precipitationPercent: 12,
isSelected: index == 0) isSelected: index == 0)
array.append(hourly) array.append(hourly)
} }
......
...@@ -10,25 +10,57 @@ import WidgetKit ...@@ -10,25 +10,57 @@ import WidgetKit
import OneWeatherCore import OneWeatherCore
struct WeatherEntry: TimelineEntry { struct WeatherEntry: TimelineEntry {
static let defaultLocation = Location(deviceLocation: true, static let defaultLocation: Location = {
lastWeatherUpdateDate: Date(timeIntervalSinceNow: -4 * 3600), func generateHourly() -> [HourlyWeather] {
coordinates: .init(latitude: 37.3230, longitude: -122.0322), var array = [HourlyWeather]()
countryName: "USA",
region: "US", for index in 1...7 {
cityName: "Cupertino", // Cupertino let hourly = HourlyWeather(lastTimeUpdated: Date(),
timeZone: TimeZone(abbreviation: "PST")!, date: Date(timeIntervalSinceNow: TimeInterval(index * 3600)),
today: .init(lastTimeUpdated: Date(timeIntervalSinceNow: -4 * 3600), timeZone: TimeZone(abbreviation: "PST")!,
date: Date(), weekDay: WeekDay.init(grigorianWeekDayNumber: index) ?? .monday,
timeZone: TimeZone.current, type: .partlyCloudy,
weekDay: .monday, isDay: true,
type: .partlyCloudy, temp: .init(value: 69 + Double(index) * 2, unit: .fahrenheit),
isDay: true, dewPoint: .init(value: 69 + Double(index) * 2, unit: .fahrenheit),
minTemp: .init(value: 89, unit: .fahrenheit), apparentTemp: .init(value: 65 + Double(index) * 2, unit: .fahrenheit),
maxTemp: .init(value: 97, unit: .fahrenheit), windSpeed: .init(value: Double(8 + index), unit: .metersPerSecond),
temp: .init(value: 96, unit: .fahrenheit)), windDirection: .northNorthEast,
daily: [], precipitationProbability: 55,
hourly: [], humidity: 80)
dayTimeForecast: []) array.append(hourly)
}
return array
}
func generateDaily() -> [DailyWeather] {
var array = [DailyWeather]()
return array
}
let loc = Location(deviceLocation: true,
lastWeatherUpdateDate: Date(timeIntervalSinceNow: -4 * 3600),
coordinates: .init(latitude: 37.3230, longitude: -122.0322),
countryName: "USA",
region: "US",
cityName: "Cupertino", // Cupertino
timeZone: TimeZone(abbreviation: "PST")!,
today: .init(lastTimeUpdated: Date(timeIntervalSinceNow: -4 * 3600),
date: Date(),
timeZone: TimeZone.current,
weekDay: .monday,
type: .partlyCloudy,
isDay: true,
minTemp: .init(value: 89, unit: .fahrenheit),
maxTemp: .init(value: 97, unit: .fahrenheit),
temp: .init(value: 96, unit: .fahrenheit)),
daily: generateDaily(),
hourly: generateHourly(),
dayTimeForecast: [])
return loc
}()
let date: Date let date: Date
let location: Location let location: Location
......
...@@ -10,8 +10,7 @@ import SwiftUI ...@@ -10,8 +10,7 @@ import SwiftUI
@main @main
struct OneWeatherWidgets: WidgetBundle { struct OneWeatherWidgets: WidgetBundle {
var body: some Widget { var body: some Widget {
SmallTemperatureWidget() TemperatureWidget()
MediumTemperatureWidget() PrecipitationWidget()
LargeTemperatureWidget()
} }
} }
...@@ -10,12 +10,16 @@ import OneWeatherCore ...@@ -10,12 +10,16 @@ import OneWeatherCore
import OneWeatherUI import OneWeatherUI
private struct Formatter { private struct Formatter {
private static let fmt: DateFormatter = { private static var fmt: DateFormatter = {
let formatter = DateFormatter() let formatter = DateFormatter()
formatter.dateFormat = "h a" formatter.dateFormat = "h a"
return formatter return formatter
}() }()
static func set(timeZone: TimeZone) {
fmt.timeZone = timeZone
}
static func dateString(date: Date) -> String { static func dateString(date: Date) -> String {
return fmt.string(from: date) return fmt.string(from: date)
} }
...@@ -42,6 +46,7 @@ struct ForecastWidgetViewModel: WidgetViewModel { ...@@ -42,6 +46,7 @@ struct ForecastWidgetViewModel: WidgetViewModel {
for index in 0..<min(modelHourly.count, 4) { for index in 0..<min(modelHourly.count, 4) {
let hourly = modelHourly[index] let hourly = modelHourly[index]
let isSelected = Calendar.isNow(fromDate: hourly.date, timeZone: hourly.timeZone) let isSelected = Calendar.isNow(fromDate: hourly.date, timeZone: hourly.timeZone)
Formatter.set(timeZone: hourly.timeZone)
let dateString = isSelected ? "day.now".localized().uppercased() : Formatter.dateString(date: hourly.date) let dateString = isSelected ? "day.now".localized().uppercased() : Formatter.dateString(date: hourly.date)
let widgetHourly = WidgetHourlyWeather(dateString: dateString, let widgetHourly = WidgetHourlyWeather(dateString: dateString,
temp: hourly.temp?.settingsConvertedValue ?? 0, temp: hourly.temp?.settingsConvertedValue ?? 0,
...@@ -50,6 +55,7 @@ struct ForecastWidgetViewModel: WidgetViewModel { ...@@ -50,6 +55,7 @@ struct ForecastWidgetViewModel: WidgetViewModel {
windSpeedLocalized: hourly.windSpeed?.settingsConverted.shortString ?? "", windSpeedLocalized: hourly.windSpeed?.settingsConverted.shortString ?? "",
windDirection: hourly.windDirection?.fullLocalized ?? "", windDirection: hourly.windDirection?.fullLocalized ?? "",
windDegrees: hourly.windDirection?.degrees ?? 0, windDegrees: hourly.windDirection?.degrees ?? 0,
precipitationPercent: Int(hourly.precipitationProbability ?? 0),
isSelected: isSelected) isSelected: isSelected)
array.append(widgetHourly) array.append(widgetHourly)
} }
......
//
// PrecipitationWidget.swift
// OneWeatherWidgetExtension
//
// Created by Dmitry Stepanets on 15.07.2021.
//
import WidgetKit
import SwiftUI
import OneWeatherUI
import Localize_Swift
struct PrecipitationWidget: Widget {
private let kind = "com.onelouder.oneweather.widget.precipitation"
var body: some WidgetConfiguration {
// We currently display selectedLocation, so it's not really configurable,
// but we'll probably need to switch to an IntentConfiguration at some point.
StaticConfiguration(kind: kind,
provider: WeatherProvider()
) { weatherEntry in
MediumPrecipitationWidgetView(widgetViewModel: ForecastWidgetViewModel(location: weatherEntry.location))
}
.configurationDisplayName("widget.precipitation.title".localized())
.description("widget.precipitation.description".localized())
.supportedFamilies([.systemMedium])
}
}
...@@ -14,21 +14,22 @@ struct TemperatureWidget: Widget { ...@@ -14,21 +14,22 @@ struct TemperatureWidget: Widget {
private let kind = "com.onelouder.oneweather.widget.temperature" private let kind = "com.onelouder.oneweather.widget.temperature"
var body: some WidgetConfiguration { var body: some WidgetConfiguration {
// We currently display selectedLocation, so it's not really configurable, but we'll probably need to switch to an IntentConfiguration at some point. // We currently display selectedLocation, so it's not really configurable,
// but we'll probably need to switch to an IntentConfiguration at some point.
StaticConfiguration(kind: kind, StaticConfiguration(kind: kind,
provider: WeatherProvider() provider: WeatherProvider()
) { weatherEntry in ) { weatherEntry in
WidgetView(entry: weatherEntry) WidgetView(entry: weatherEntry)
} }
.configurationDisplayName("widget.small.title".localized()) .configurationDisplayName("widget.temperature.title".localized())
.description("widget.small.description".localized()) .description("widget.temperature.description".localized())
.supportedFamilies([.systemSmall, .systemMedium, .systemLarge]) .supportedFamilies([.systemSmall, .systemMedium])
} }
} }
private struct WidgetView: View { private struct WidgetView: View {
@Environment(\.widgetFamily) private var widgetSize @Environment(\.widgetFamily) private var widgetSize
let entry: WeatherEntry let entry: WeatherEntry
var body: some View { var body: some View {
let viewModel = ForecastWidgetViewModel(location: entry.location) let viewModel = ForecastWidgetViewModel(location: entry.location)
...@@ -46,11 +47,13 @@ private struct WidgetView: View { ...@@ -46,11 +47,13 @@ private struct WidgetView: View {
} }
} }
struct SmallTemperatureWidgetView_Preview: PreviewProvider { struct WidgetView_Preview: PreviewProvider {
public static var previews: some View { public static var previews: some View {
SmallTemperatureWidgetView(widgetViewModel: nil) WidgetView(entry: WeatherEntry(location: WeatherEntry.defaultLocation,
date: Date()))
.preferredColorScheme(.dark) .preferredColorScheme(.dark)
.previewContext(WidgetPreviewContext(family: .systemSmall)) .previewDevice("iPhone 11")
.previewContext(WidgetPreviewContext(family: .systemMedium))
} }
} }
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