Skip to content

Instantly share code, notes, and snippets.

@chriseidhof
Created February 5, 2020 18:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chriseidhof/7cfdb486e316bd11580acf7769140a5c to your computer and use it in GitHub Desktop.
Save chriseidhof/7cfdb486e316bd11580acf7769140a5c to your computer and use it in GitHub Desktop.
//
// ContentView.swift
// Store
//
// Created by Chris Eidhof on 05.02.20.
// Copyright © 2020 Chris Eidhof. All rights reserved.
//
import SwiftUI
final class Store<A>: ObservableObject {
@Published var value: A
init(_ value: A) {
self.value = value
}
}
enum Action {
case addTodo(String)
case toggle(UUID)
case delete(UUID)
}
protocol Elmy {
associatedtype Message
associatedtype V: View
typealias Send = (Message) -> ()
func run(_ send: @escaping Send) -> V
}
extension Store where A == [Todo] {
func interpret(action: Action) {
switch action {
case .addTodo(let title):
value.append(Todo(title: title))
case .toggle(let id):
guard let i = value.firstIndex(where: { $0.id == id }) else { return }
value[i].done.toggle()
case .delete(let id):
value.removeAll(where: { $0.id == id })
}
}
}
struct Todo: Identifiable {
var id = UUID()
var title: String
var done = false
}
let todos: [Todo] = []
struct AllTodos: Elmy {
var todos: [Todo]
func run(_ send: @escaping (Action) -> ()) -> some View {
List {
ForEach(todos) { todo in
Button(action: {
send(.toggle(todo.id))
}) {
HStack {
Text(todo.title)
Spacer()
if todo.done {
Text("✓")
}
}
}
}.onDelete(perform: { ix in
for id in ix.map({ self.todos[$0].id }) {
send(.delete(id))
}
})
}.navigationBarItems(trailing: Button("+", action: {
send(.addTodo("New Todo"))
}))
}
}
struct ContentView: View {
@ObservedObject var store = Store(todos)
var body: some View {
NavigationView {
AllTodos(todos: store.value).run(self.store.interpret)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment