Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions Application/DevLogApp/Sources/App/DevLogApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ struct DevLogApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
@Environment(\.diContainer) var container: DIContainer
@Environment(\.scenePhase) var scenePhase
@State private var windowEvent = TodoEditorWindowEvent()

init() {
AppAssembler().assemble(AppDIContainer.shared)
Expand All @@ -33,10 +34,23 @@ struct DevLogApp: App {
clearPushNotificationRoute: { PushNotificationRoute.shared.clear() }
)
.autocorrectionDisabled()
.environment(windowEvent)
.onChange(of: scenePhase) { _, phase in
guard phase == .background else { return }
container.resolve(WidgetSyncEventBus.self).publish(.syncRequested)
}
}
WindowGroup(id: TodoEditorWindowValue.sceneId, for: TodoEditorWindowValue.self) { value in
if let value = value.wrappedValue {
TodoEditorWindowView(value: value)
.autocorrectionDisabled()
.environment(windowEvent)
} else {
ContentUnavailableView(
String(localized: "todo_edit"),
systemImage: "square.and.pencil"
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ extension EnvironmentValues {
self[SceneHeightKey.self]
}

var isiOSAppOnMac: Bool {
self[IOSAppOnMacKey.self]
}

private struct SafeAreaInsetsKey: EnvironmentKey {
static var defaultValue: EdgeInsets {
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
Expand Down Expand Up @@ -48,6 +52,12 @@ extension EnvironmentValues {
return windowScene.screen.bounds.height
}
}

private struct IOSAppOnMacKey: EnvironmentKey {
static var defaultValue: Bool {
ProcessInfo.processInfo.isiOSAppOnMac
}
}
}

extension UIEdgeInsets {
Expand Down
28 changes: 27 additions & 1 deletion Application/DevLogPresentation/Sources/Home/Home/HomeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import SwiftUI
import DevLogDomain

struct HomeView: View {
@Environment(TodoEditorWindowEvent.self) private var windowEvent
@Environment(\.openWindow) private var openWindow
@Environment(\.isiOSAppOnMac) private var isiOSAppOnMac
@ScaledMetric(relativeTo: .largeTitle) private var labelWidth = CGFloat(34)
let coordinator: HomeViewCoordinator
let isCompactLayout: Bool
Expand Down Expand Up @@ -87,6 +90,9 @@ struct HomeView: View {
LoadingView()
}
}
.onChange(of: windowEvent.submitted) { _, submitted in
handleTodoEditorSubmit(submitted)
}
}

@ViewBuilder
Expand Down Expand Up @@ -272,6 +278,7 @@ struct HomeView: View {
} label: {
RecentTodoRow(todo: item)
.frame(maxWidth: .infinity, alignment: .leading)
.contentShape(.rect)
}
.buttonStyle(.plain)
}
Expand All @@ -290,6 +297,7 @@ struct HomeView: View {
} label: {
WebItemRow(item: item, showsChevron: false)
.frame(maxWidth: .infinity, alignment: .leading)
.contentShape(.rect)
}
.buttonStyle(.plain)
}
Expand All @@ -314,7 +322,7 @@ struct HomeView: View {
ForEach(preferences, id: \.id) { item in
Button {
DispatchQueue.main.async {
coordinator.viewModel.send(.tapTodoCategory(item.category))
openTodoEditor(for: item.category)
}
} label: {
labelImage(
Expand Down Expand Up @@ -384,6 +392,24 @@ struct HomeView: View {
.contentShape(.rect)
}

private func openTodoEditor(for todoCategory: TodoCategory) {
if isiOSAppOnMac {
coordinator.viewModel.send(.setPresentation(.contentPicker, false))
openWindow(
id: TodoEditorWindowValue.sceneId,
value: TodoEditorWindowValue(todoCategory: todoCategory, source: .home)
)
} else {
coordinator.viewModel.send(.tapTodoCategory(todoCategory))
}
}

private func handleTodoEditorSubmit(_ submit: TodoEditorWindowSubmit?) {
guard let submit,
submit.value.matchesCreate(source: .home) else { return }
coordinator.viewModel.send(.addTodo(submit.todo))
}

}

enum HomeRoute: Hashable {
Expand Down
26 changes: 25 additions & 1 deletion Application/DevLogPresentation/Sources/Home/TodoDetailView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import DevLogDomain

struct TodoDetailView: View {
@Environment(\.diContainer) private var container: DIContainer
@Environment(TodoEditorWindowEvent.self) private var windowEvent
@Environment(\.openWindow) private var openWindow
@Environment(\.isiOSAppOnMac) private var isiOSAppOnMac
@State var viewModel: TodoDetailViewModel

var body: some View {
Expand All @@ -29,6 +32,9 @@ struct TodoDetailView: View {
}
}
.onAppear { viewModel.send(.onAppear) }
.onChange(of: windowEvent.submitted) { _, submitted in
handleTodoEditorSubmit(submitted)
}
.navigationBarTitleDisplayMode(.inline)
.sheet(isPresented: Binding(
get: { viewModel.state.showInfo },
Expand Down Expand Up @@ -90,14 +96,32 @@ struct TodoDetailView: View {
}
ToolbarItem(placement: .topBarTrailing) {
Button {
viewModel.send(.setShowEditor(true))
openTodoEditor()
} label: {
Text(String(localized: "todo_edit"))
}
}
}
}

private func openTodoEditor() {
if isiOSAppOnMac {
guard let todo = viewModel.state.todo else { return }
openWindow(
id: TodoEditorWindowValue.sceneId,
value: TodoEditorWindowValue(todo: todo)
)
} else {
viewModel.send(.setShowEditor(true))
}
}

private func handleTodoEditorSubmit(_ submit: TodoEditorWindowSubmit?) {
guard let submit,
submit.value.matchesEdit(todoId: viewModel.todoId) else { return }
viewModel.send(.upsertTodo(submit.todo))
}

@ViewBuilder
private var sheetContent: some View {
if let todo = viewModel.state.todo {
Expand Down
43 changes: 36 additions & 7 deletions Application/DevLogPresentation/Sources/Home/TodoEditorView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,17 @@ struct TodoEditorView: View {
@State var viewModel: TodoEditorViewModel
@Environment(\.diContainer) private var container: DIContainer
@Environment(\.dismiss) private var dismiss
@Environment(\.isiOSAppOnMac) private var isiOSAppOnMac
@FocusState private var field: Field?
private let calendar = Calendar.current
var onSubmit: ((Todo) -> Void)?
var onClose: (() -> Void)?

var body: some View {
NavigationStack {
ScrollView {
LazyVStack(spacing: 10) {
titleField
titleSection
LazyVStack(
alignment: .leading,
spacing: 0,
Expand All @@ -32,7 +34,10 @@ struct TodoEditorView: View {
Section {
tabView
} header: {
tabViewSelector
if !isiOSAppOnMac {
tabPicker
.padding(.horizontal)
}
}
}
}
Expand Down Expand Up @@ -74,7 +79,9 @@ struct TodoEditorView: View {
.presentationDragIndicator(.visible)
}
.toolbar {
ToolbarLeadingButton { dismiss() }
if !isiOSAppOnMac {
ToolbarLeadingButton { close() }
}
ToolbarItem(placement: .topBarTrailing) {
Button {
viewModel.send(.setShowInfo(true))
Expand All @@ -90,6 +97,22 @@ struct TodoEditorView: View {
}
}

@ViewBuilder
private var titleSection: some View {
Group {
if isiOSAppOnMac {
HStack(spacing: 12) {
titleField
tabPicker
.frame(width: 180)
}
} else {
titleField
}
}
.padding(.horizontal)
}

private var titleField: some View {
TextField(
"",
Expand All @@ -102,10 +125,9 @@ struct TodoEditorView: View {
.font(.title2)
.frame(height: 30)
.focused($field, equals: .title)
.padding(.horizontal)
}

private var tabViewSelector: some View {
private var tabPicker: some View {
Picker(
"",
selection: Binding(
Expand All @@ -126,7 +148,6 @@ struct TodoEditorView: View {
.tag(TodoEditorViewModel.Tag.preview)
}
.pickerStyle(.segmented)
.padding(.horizontal)
}

private var tabView: some View {
Expand Down Expand Up @@ -180,7 +201,15 @@ struct TodoEditorView: View {
private func submit() {
let todo = viewModel.makeTodo()
onSubmit?(todo)
dismiss()
close()
}

private func close() {
if let onClose {
onClose()
} else {
dismiss()
}
}

private func transitionToPreview() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// TodoEditorWindowEvent.swift
// DevLogPresentation
//
// Created by opfic on 5/31/26.
//

import Foundation
import DevLogDomain

@MainActor
@Observable
public final class TodoEditorWindowEvent {
var submitted: TodoEditorWindowSubmit?

public init() { }

func submit(
value: TodoEditorWindowValue,
todo: Todo
) {
submitted = TodoEditorWindowSubmit(value: value, todo: todo)
}
}
Comment thread
opficdev marked this conversation as resolved.
Outdated
Loading
Loading