Skip to content

Commit

Permalink
Merge pull request #3 from jhrcook/watch-app
Browse files Browse the repository at this point in the history
Watch app
  • Loading branch information
jhrcook authored Aug 25, 2020
2 parents bdb97aa + 240e2c6 commit 7f670b4
Show file tree
Hide file tree
Showing 65 changed files with 2,542 additions and 81 deletions.
21 changes: 19 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,23 @@ An iOS application written in SwiftUI to help keep track of watering plants.

See the [Projects](https://github.com/jhrcook/WaterMe/projects/1) tab to view the To-Do list.

<img width="400px" src="demos/detailview-demo.gif">
### Edit logged watering dates

<img width="400px" src="demos/multiselect-demo.gif">
<img width="400px" src="demos/waterme-editloggedwaters.gif">

### Water multiple plants at once

<img width="400px" src="demos/waterme-makeitrain.gif">

### Set up watering notifications

<img width="400px" src="demos/waterme-setupnotifications.gif">

### Companion Watch app

<img height="220px" src="demos/waterme-watch-ui.gif">
<img height="220px" src="demos/waterme-watch-image.png">

### Can water a plant from the watch

<img width="400px" src="demos/waterme-watch-connectivity.gif">
405 changes: 404 additions & 1 deletion WaterMe.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

21 changes: 20 additions & 1 deletion WaterMe/Extensions/Color-extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,26 @@ extension Color {
/// - adobeS: Saturation (out of 100)
/// - adobeB: Brightness (out of 100)
init(adobeH: Double, adobeS: Double, adobeB: Double) {
self.init(hue: adobeH / 360.0, saturation: adobeS / 100.0, brightness: adobeB / 100.0)
self.init(hue: adobeH / 360.0,
saturation: adobeS / 100.0,
brightness: adobeB / 100.0)
}

static let darkBlue = Color(adobeH: 205, adobeS: 62, adobeB: 66)
static let lightBlue = Color(adobeH: 205, adobeS: 52, adobeB: 96)
static let lightTomato = Color(adobeH: 1, adobeS: 52, adobeB: 96)


init(red255: Double, green255: Double, blue255: Double) {
self.init(red: red255 / 255.0,
green: green255 / 255.0,
blue: blue255 / 255.0)
}

static let mySystemGrey3 = Color(red255: 72, green255: 72, blue255: 74)
static let mySystemGrey4 = Color(red255: 58, green255: 58, blue255: 60)
static let mySystemGrey5 = Color(red255: 44, green255: 44, blue255: 46)
static let mySystemGrey6 = Color(red255: 28, green255: 28, blue255: 30)
}


Expand Down Expand Up @@ -54,6 +68,11 @@ struct CustomColors_Previews: PreviewProvider {
ExampleColorText(text: "Dark Blue", backgroundColor: .darkBlue)
ExampleColorText(text: "Light Blue", backgroundColor: .lightBlue)
ExampleColorText(text: "Light Tomato", backgroundColor: .lightTomato)

ExampleColorText(text: "mySystemGrey3", backgroundColor: .mySystemGrey3)
ExampleColorText(text: "mySystemGrey4", backgroundColor: .mySystemGrey4)
ExampleColorText(text: "mySystemGrey5", backgroundColor: .mySystemGrey5)
ExampleColorText(text: "mySystemGrey6", backgroundColor: .mySystemGrey6)
}

}
Expand Down
17 changes: 17 additions & 0 deletions WaterMe/Extensions/KeyboardDismiss-extension.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// KeyboardDismiss-extension.swift
// WaterMe
//
// Created by Joshua on 8/1/20.
// Copyright © 2020 Joshua Cook. All rights reserved.
//

import SwiftUI

#if canImport(UIKit)
extension View {
func hideKeyboard() {
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
}
#endif
29 changes: 29 additions & 0 deletions WaterMe/Extensions/UIImage-extension.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// UIImage-extension.swift
// WaterMe
//
// Created by Joshua on 8/24/20.
// Copyright © 2020 Joshua Cook. All rights reserved.
//

import UIKit


extension UIImage {
func resized(withPercentage percentage: CGFloat, isOpaque: Bool = true) -> UIImage? {
let canvas = CGSize(width: size.width * percentage, height: size.height * percentage)
let format = imageRendererFormat
format.opaque = isOpaque
return UIGraphicsImageRenderer(size: canvas, format: format).image {
_ in draw(in: CGRect(origin: .zero, size: canvas))
}
}
func resized(toWidth width: CGFloat, isOpaque: Bool = true) -> UIImage? {
let canvas = CGSize(width: width, height: CGFloat(ceil(width/size.width * size.height)))
let format = imageRendererFormat
format.opaque = isOpaque
return UIGraphicsImageRenderer(size: canvas, format: format).image {
_ in draw(in: CGRect(origin: .zero, size: canvas))
}
}
}
26 changes: 22 additions & 4 deletions WaterMe/Mainviews/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@


struct ContentView: View {

@ObservedObject var garden = Garden()

@Environment(\.colorScheme) var colorScheme
Expand All @@ -37,6 +37,8 @@

@State private var forceAnimationToResetView = false

var watchCommunicator = PhoneToWatchCommunicator()

var body: some View {
NavigationView {
ZStack {
Expand All @@ -58,7 +60,8 @@
multiselectMode: self.$isInMultiselectMode,
multiselectedPlants: self.$multiselectedPlants,
cellSpacing: cellSpacing,
forceAnimationToResetView: self.$forceAnimationToResetView)
forceAnimationToResetView: self.$forceAnimationToResetView,
watchCommunicator: self.watchCommunicator)
.frame(width: geo.size.width, height: self.calculateHeightForCell(from: geo.size.width, withCellSpacing: cellSpacing))
}
}
Expand Down Expand Up @@ -94,7 +97,9 @@

}
.frame(maxHeight: .infinity)
.sheet(isPresented: self.$showSettings, content: { SettingsView(garden: self.garden) })
.sheet(isPresented: self.$showSettings) {
SettingsView(garden: self.garden, watchCommunicator: self.watchCommunicator)
}
}

VStack {
Expand Down Expand Up @@ -146,6 +151,7 @@
if selectedPlant.id == plant.id {
plant.addNewDateLastWatered(to: Date())
self.garden.plants[i] = plant
self.watchCommunicator.updateOnWatch(plant)
}
}
}
Expand Down Expand Up @@ -173,11 +179,13 @@
.navigationBarHidden(true)
}
.sheet(isPresented: $showNewPlantView) {
MakeNewPlantView(garden: self.garden)
MakeNewPlantView(garden: self.garden,
watchCommunicator: self.watchCommunicator)
}
.onAppear {
print("There are \(self.garden.plants.count) plants in `garden`.")
UITableView.appearance().separatorStyle = .none
self.watchCommunicator.gardenDelegate = self
}
}

Expand All @@ -190,6 +198,16 @@
}



extension ContentView: GardenDelegate {
func gardenDidChange() {
print("Garden did change.")
garden.reloadPlants()
forceAnimationToResetView.toggle()
}
}


struct ContentView_Previews: PreviewProvider {
static var previews: some View {
Group {
Expand Down
9 changes: 6 additions & 3 deletions WaterMe/Mainviews/EditNotificationView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ struct EditNotificationView: View {

@Binding var plant: Plant
@ObservedObject var garden: Garden
var watchCommunicator: PhoneToWatchCommunicator

@State var plantHasNotificationsSet: Bool
@State private var selectedNotificationType: WaterNotificationType
Expand All @@ -20,9 +21,10 @@ struct EditNotificationView: View {
@State private var weekdayFrequency: Int
@State private var numberOfDaysPerNotification: Int

init(plant: Binding<Plant>, garden: Garden) {
init(plant: Binding<Plant>, garden: Garden, watchCommunicator: PhoneToWatchCommunicator) {
_plant = plant
self.garden = garden
self.watchCommunicator = watchCommunicator

_plantHasNotificationsSet = State(initialValue: plant.wrappedValue.wateringNotification != nil)
_selectedNotificationType = State(initialValue: plant.wrappedValue.wateringNotification?.type ?? WaterNotificationType.weekday)
Expand Down Expand Up @@ -93,6 +95,7 @@ struct EditNotificationView: View {
if !self.plantHasNotificationsSet {
self.plant.wateringNotification = nil
self.garden.update(self.plant)
self.watchCommunicator.updateOnWatch(self.plant)
return
}

Expand All @@ -109,6 +112,7 @@ struct EditNotificationView: View {
// Schedule the notification and update garden.
self.plant.scheduleNotification()
self.garden.update(self.plant)
self.watchCommunicator.updateOnWatch(self.plant)
}
}
}
Expand All @@ -117,8 +121,7 @@ struct EditNotificationView: View {
struct EditNotificationView_Previews: PreviewProvider {
static var previews: some View {
Group {
EditNotificationView(plant: .constant(Plant(name: "Test plant")), garden: Garden())
EditNotificationView(plant: .constant(Plant(name: "Test plant")), garden: Garden(), watchCommunicator: PhoneToWatchCommunicator())
}

}
}
14 changes: 9 additions & 5 deletions WaterMe/Mainviews/MakeNewPlantView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ struct MakeNewPlantView: View {

@State private var userSelectedImage: UIImage?

var watchCommunicator: PhoneToWatchCommunicator

var body: some View {
NavigationView {
Form {
Expand Down Expand Up @@ -78,22 +80,24 @@ struct MakeNewPlantView: View {
func savePlant() {
var datesWatered = [Date]()
if setDateLastWatered {
datesWatered.append(self.dateLastWatered)
datesWatered.append(dateLastWatered)
}

var newPlant = Plant(name: self.plantName, datesWatered: datesWatered)
var newPlant = Plant(name: plantName, datesWatered: datesWatered)
if let uiImage = userSelectedImage {
newPlant.savePlantImage(uiImage: uiImage)
}

self.garden.plants.append(newPlant)
self.presentationMode.wrappedValue.dismiss()
garden.plants.append(newPlant)
watchCommunicator.addToWatch(newPlant)
watchCommunicator.transferImageToWatch(newPlant, andSendUpdatedPlant: false)
presentationMode.wrappedValue.dismiss()
}

}

struct MakeNewPlantView_Previews: PreviewProvider {
static var previews: some View {
MakeNewPlantView(garden: Garden())
MakeNewPlantView(garden: Garden(), watchCommunicator: PhoneToWatchCommunicator())
}
}
Loading

0 comments on commit 7f670b4

Please sign in to comment.