Commit 1d9efe87 by Demid Merzlyakov

IOS-72: refactor small widget to extract views shared with bigger widgets.

parent 4de104bf
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"colors" : [
{
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.741",
"green" : "0.673",
"red" : "0.656"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
//
// OneWeatherWidgetsBundle.swift
// OneWeatherWidgetExtension
//
// Created by Demid Merzlyakov on 28.06.2021.
//
import SwiftUI
@main
struct OneWeatherWidgets: WidgetBundle {
var body: some Widget {
SmallTemperatureWidget()
}
}
...@@ -14,10 +14,10 @@ struct WidgetPlaceholderView: View { ...@@ -14,10 +14,10 @@ struct WidgetPlaceholderView: View {
var body: some View { var body: some View {
switch family { switch family {
case .systemSmall: case .systemSmall:
SmallWidgetView(widgetViewModel: .init(location: WeatherEntry.defaultLocation)) SmallTemperatureWidgetView(widgetViewModel: .init(location: WeatherEntry.defaultLocation))
.redacted(reason: .placeholder) .redacted(reason: .placeholder)
default: default:
SmallWidgetView(widgetViewModel: .init(location: WeatherEntry.defaultLocation)) SmallTemperatureWidgetView(widgetViewModel: .init(location: WeatherEntry.defaultLocation))
.redacted(reason: .placeholder) .redacted(reason: .placeholder)
} }
} }
......
//
// CityNameView.swift
// OneWeatherWidgetExtension
//
// Created by Demid Merzlyakov on 01.07.2021.
//
import SwiftUI
struct CityNameView: View {
@State public var cityName: String
@State public var isDeviceLocation: Bool
var body: some View {
HStack(spacing: 4) {
Text(cityName)
.multilineTextAlignment(.leading)
.font(AppFont.SFProDisplay.regular(size: 12).font)
.foregroundColor(ThemeManager.currentTheme.graphTintColor.color)
Image("location_arrow")
.resizable()
.renderingMode(.template)
.frame(width: 8, height: 8, alignment: .center)
.aspectRatio(contentMode: .fit)
.foregroundColor(Color(ThemeManager.currentTheme.graphTintColor.cgColor))
.opacity(isDeviceLocation ? 1 : 0)
}
}
}
//
// HighLowTemperatureView.swift
// OneWeatherWidgetExtension
//
// Created by Demid Merzlyakov on 01.07.2021.
//
import SwiftUI
struct HighLowTemperatureView: View {
@State public var highTemperature: String
@State public var lowTemperature: String
var body: some View {
HStack {
Text("H \(highTemperature)")
.font(AppFont.SFProDisplay.regular(size: 12).font)
.foregroundColor(Color("HighLowTemperatureColor"))
Text("L \(lowTemperature)")
.font(AppFont.SFProDisplay.regular(size: 12).font)
.foregroundColor(Color("HighLowTemperatureColor"))
}
}
}
...@@ -9,9 +9,9 @@ import SwiftUI ...@@ -9,9 +9,9 @@ import SwiftUI
import WidgetKit import WidgetKit
import OneWeatherCore import OneWeatherCore
struct SmallWidgetView: View { struct SmallTemperatureWidgetView: View {
//Public //Public
let widgetViewModel: SmallWidgetViewModel let widgetViewModel: ForecastWidgetViewModel
//Private //Private
@Environment(\.colorScheme) private var colorScheme @Environment(\.colorScheme) private var colorScheme
...@@ -29,17 +29,8 @@ struct SmallWidgetView: View { ...@@ -29,17 +29,8 @@ struct SmallWidgetView: View {
GeometryReader { geometry in GeometryReader { geometry in
VStack { VStack {
HStack(spacing: 4) { HStack(spacing: 4) {
Text(widgetViewModel.cityName) CityNameView(cityName: widgetViewModel.cityName,
.multilineTextAlignment(.leading) isDeviceLocation: widgetViewModel.isDeviceLocation)
.font(AppFont.SFProDisplay.regular(size: 12).font)
.foregroundColor(ThemeManager.currentTheme.graphTintColor.color)
Image("location_arrow")
.resizable()
.renderingMode(.template)
.frame(width: 8, height: 8, alignment: .center)
.aspectRatio(contentMode: .fit)
.foregroundColor(Color(ThemeManager.currentTheme.graphTintColor.cgColor))
.opacity(widgetViewModel.isDeviceLocation ? 1 : 0)
Spacer() Spacer()
} }
.padding(.top, 12) .padding(.top, 12)
...@@ -51,12 +42,12 @@ struct SmallWidgetView: View { ...@@ -51,12 +42,12 @@ struct SmallWidgetView: View {
.font(AppFont.SFProDisplay.light(size: 32).font) .font(AppFont.SFProDisplay.light(size: 32).font)
.padding(.leading, 10) .padding(.leading, 10)
.padding(.trailing, 4) .padding(.trailing, 4)
.textColor(for: interfaceStyle) .textColor(for: colorScheme)
Text(widgetViewModel.weatherType) Text(widgetViewModel.weatherType)
.font(AppFont.SFProDisplay.regular(size: 12).font) .font(AppFont.SFProDisplay.regular(size: 12).font)
.padding(.leading, 10) .padding(.leading, 10)
.padding(.trailing, 4) .padding(.trailing, 4)
.textColor(for: interfaceStyle) .textColor(for: colorScheme)
Spacer(minLength: 0) Spacer(minLength: 0)
} }
.frame(height: 70) .frame(height: 70)
...@@ -66,20 +57,15 @@ struct SmallWidgetView: View { ...@@ -66,20 +57,15 @@ struct SmallWidgetView: View {
.resizable() .resizable()
.aspectRatio(contentMode: .fit) .aspectRatio(contentMode: .fit)
.frame(width: 70, height: 70, alignment: .center) .frame(width: 70, height: 70, alignment: .center)
.shadow(for: interfaceStyle) .shadow(for: colorScheme)
.padding(.trailing, 4) .padding(.trailing, 4)
} }
HStack { HStack {
Text("H \(widgetViewModel.highTemperature)") HighLowTemperatureView(highTemperature: widgetViewModel.highTemperature,
.font(AppFont.SFProDisplay.regular(size: 12).font) lowTemperature: widgetViewModel.lowTemperature)
.footerTextColor(for: interfaceStyle)
Text("L \(widgetViewModel.lowTemperature)")
.font(AppFont.SFProDisplay.regular(size: 12).font)
.footerTextColor(for: interfaceStyle)
Spacer() Spacer()
} }
// .padding(.top, 20)
.padding(.bottom, 21) .padding(.bottom, 21)
.padding(.leading, 10) .padding(.leading, 10)
} }
...@@ -89,38 +75,33 @@ struct SmallWidgetView: View { ...@@ -89,38 +75,33 @@ struct SmallWidgetView: View {
//MARK: Appearence extension //MARK: Appearence extension
private extension View { private extension View {
func shadow(for interfaceStyle:AppInterfaceStyle) -> some View { func shadow(for colorScheme: ColorScheme) -> some View {
switch interfaceStyle { switch colorScheme {
case .light: case .light:
return self.shadow(color: Color.black.opacity(0.5), radius: 16, x: 2, y: 0) return self.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) return self.shadow(color: Color.white.opacity(0.24), radius: 16, x: 2, y: 0)
@unknown default:
return self.shadow(color: Color.black.opacity(0.5), radius: 16, x: 2, y: 0)
} }
} }
func textColor(for interfaceStyle:AppInterfaceStyle) -> some View { func textColor(for colorScheme: ColorScheme) -> some View {
switch interfaceStyle { switch colorScheme {
case .light: case .light:
return self.foregroundColor(ThemeManager.currentTheme.secondaryTextColor.color) return self.foregroundColor(ThemeManager.currentTheme.secondaryTextColor.color)
case .dark: case .dark:
return self.foregroundColor(ThemeManager.currentTheme.primaryTextColor.color) return self.foregroundColor(ThemeManager.currentTheme.primaryTextColor.color)
} @unknown default:
} return self.foregroundColor(ThemeManager.currentTheme.secondaryTextColor.color)
func footerTextColor(for interfaceStyle:AppInterfaceStyle) -> some View {
switch interfaceStyle {
case .light:
return self.foregroundColor(UIColor(hex: 0xA6ACbe).color)
case .dark:
return self.foregroundColor(UIColor(hex: 0xA9BAC5).color)
} }
} }
} }
struct SmallWidget_Preview: PreviewProvider { struct SmallTemperatureWidgetView_Preview: PreviewProvider {
static var previews: some View { static var previews: some View {
SmallWidgetView(widgetViewModel: .init(location: WeatherEntry.defaultLocation)) SmallTemperatureWidgetView(widgetViewModel: .init(location: WeatherEntry.defaultLocation))
.previewContext(WidgetPreviewContext(family: .systemSmall)) .previewContext(WidgetPreviewContext(family: .systemSmall))
} }
} }
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
import SwiftUI import SwiftUI
import OneWeatherCore import OneWeatherCore
struct SmallWidgetViewModel { struct ForecastWidgetViewModel {
let cityName: String let cityName: String
let temperature: String let temperature: String
let weatherType: String let weatherType: String
...@@ -17,7 +17,7 @@ struct SmallWidgetViewModel { ...@@ -17,7 +17,7 @@ struct SmallWidgetViewModel {
let lowTemperature: String let lowTemperature: String
let isDeviceLocation: Bool let isDeviceLocation: Bool
init(location:Location) { init(location: Location) {
self.cityName = location.cityName ?? "--" self.cityName = location.cityName ?? "--"
self.temperature = "\(location.today?.temp?.shortString ?? "--")" self.temperature = "\(location.today?.temp?.shortString ?? "--")"
self.weatherType = location.today?.type.localized(isDay: location.today?.isDay ?? true) ?? "--" self.weatherType = location.today?.type.localized(isDay: location.today?.isDay ?? true) ?? "--"
......
...@@ -8,14 +8,13 @@ ...@@ -8,14 +8,13 @@
import WidgetKit import WidgetKit
import SwiftUI import SwiftUI
@main struct SmallTemperatureWidget: Widget {
struct OneWeatherWidget: Widget { private let kind = "com.onelouder.oneweather.widget.small"
private let kind = "com.onelouder.oneweather.widget"
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, provider: WeatherProvider()) { weatherEntry in StaticConfiguration(kind: kind, provider: WeatherProvider()) { weatherEntry in
SmallWidgetView(widgetViewModel: .init(location: weatherEntry.location)) SmallTemperatureWidgetView(widgetViewModel: .init(location: weatherEntry.location))
} }
.supportedFamilies([.systemSmall]) .supportedFamilies([.systemSmall])
} }
......
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