Skip to content

Commit

Permalink
Merge pull request #715 from Infomaniak/refactor-navigation
Browse files Browse the repository at this point in the history
refactor: Improved navigation
  • Loading branch information
PhilippeWeidmann committed Apr 27, 2023
2 parents 9ef7cf7 + 7a78ec5 commit 8a547ce
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 57 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
jobs:
build:
name: Build and Test project
runs-on: self-hosted
runs-on: [ self-hosted, iOS ]

steps:
- name: Cancel Previous Runs
Expand Down
13 changes: 11 additions & 2 deletions .package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,15 @@
"version" : "7.5.2"
}
},
{
"identity" : "navigationbackport",
"kind" : "remoteSourceControl",
"location" : "https://github.com/johnpatrickmorgan/NavigationBackport",
"state" : {
"revision" : "5096dda355148dd40162810e7f56292ce0a2b09b",
"version" : "0.7.5"
}
},
{
"identity" : "nuke",
"kind" : "remoteSourceControl",
Expand Down Expand Up @@ -175,8 +184,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/getsentry/sentry-cocoa",
"state" : {
"revision" : "ac224c437a3070ffe34460137ac8761eddaf2852",
"version" : "8.3.3"
"revision" : "92a6472efc750a4e18bdee21c204942ab0bc4dcd",
"version" : "8.4.0"
}
},
{
Expand Down
25 changes: 23 additions & 2 deletions Mail/Views/SplitView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,21 @@ import InfomaniakCore
import Introspect
import MailCore
import MailResources
import NavigationBackport
import RealmSwift
import SwiftUI

struct MailNavigationPathKey: EnvironmentKey {
static var defaultValue: Binding<[Thread]>?
}

extension EnvironmentValues {
var mailNavigationPath: Binding<[Thread]>? {
get { self[MailNavigationPathKey.self] }
set { self[MailNavigationPathKey.self] = newValue }
}
}

class GlobalBottomSheet: DisplayedFloatingPanelState<GlobalBottomSheet.State> {
enum State {
case getMoreStorage
Expand Down Expand Up @@ -62,6 +74,7 @@ struct SplitView: View {
@StateObject private var alert = GlobalAlert()

@StateObject private var splitViewManager: SplitViewManager
@State private var path = [Thread]()

var isCompact: Bool {
sizeClass == .compact || verticalSizeClass == .compact
Expand All @@ -77,9 +90,12 @@ struct SplitView: View {
Group {
if isCompact {
ZStack {
NavigationView {
NBNavigationStack(path: $path) {
ThreadListManagerView(isCompact: isCompact)
.accessibilityHidden(navigationDrawerController.isOpen)
.nbNavigationDestination(for: Thread.self) { thread in
ThreadView(thread: thread)
}
}
.navigationViewStyle(.stack)

Expand All @@ -95,7 +111,11 @@ struct SplitView: View {

ThreadListManagerView(isCompact: isCompact)

EmptyStateView.emptyThread(from: splitViewManager.selectedFolder)
if let thread = path.last {
ThreadView(thread: thread)
} else {
EmptyStateView.emptyThread(from: splitViewManager.selectedFolder)
}
}
}
}
Expand Down Expand Up @@ -157,6 +177,7 @@ struct SplitView: View {
EmptyView()
}
}
.environment(\.mailNavigationPath, $path)
.environment(\.realmConfiguration, mailboxManager.realmConfiguration)
.environmentObject(mailboxManager)
.environmentObject(splitViewManager)
Expand Down
43 changes: 12 additions & 31 deletions Mail/Views/Thread List/ThreadListCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import SwiftUI

struct ThreadListCell: View {
@EnvironmentObject var splitViewManager: SplitViewManager
@Environment(\.mailNavigationPath) private var path

let thread: Thread

Expand All @@ -34,53 +35,33 @@ struct ThreadListCell: View {
let threadDensity: ThreadDensity

let isSelected: Bool
let isMultiSelected: Bool

@Binding var editedMessageDraft: Draft?

@State private var shouldNavigateToThreadList = false

private var selectionType: SelectionBackgroundKind {
if isSelected {
return .multiple
} else if !multipleSelectionViewModel.isEnabled && viewModel.selectedThread?.uid == thread.uid {
return .single
if multipleSelectionViewModel.isEnabled {
return isMultiSelected ? .multiple : .none
}
return .none
}

private var selectedThreadBackground: Bool {
return !multipleSelectionViewModel.isEnabled && (viewModel.selectedThread?.uid == thread.uid)
return isSelected ? .single : .none
}

var body: some View {
ZStack {
if !thread.shouldPresentAsDraft {
NavigationLink(destination: ThreadView(thread: thread,
onDismiss: { viewModel.selectedThread = nil }),
isActive: $shouldNavigateToThreadList) { EmptyView() }
.opacity(0)
.disabled(multipleSelectionViewModel.isEnabled)
}

ThreadCell(
thread: thread,
density: threadDensity,
isMultipleSelectionEnabled: multipleSelectionViewModel.isEnabled,
isSelected: isSelected
)
}
ThreadCell(
thread: thread,
density: threadDensity,
isMultipleSelectionEnabled: multipleSelectionViewModel.isEnabled,
isSelected: isMultiSelected
)
.background(SelectionBackground(selectionType: selectionType, paddingLeading: 4))
.onTapGesture { didTapCell() }
.onLongPressGesture(minimumDuration: 0.3) { didLongPressCell() }
.swipeActions(thread: thread, viewModel: viewModel, multipleSelectionViewModel: multipleSelectionViewModel)
.listRowInsets(.init(top: 0, leading: 0, bottom: 0, trailing: 0))
.listRowSeparator(.hidden)
.listRowBackground(MailResourcesAsset.backgroundColor.swiftUIColor)
.onChange(of: viewModel.selectedThread) { newThread in
if newThread?.uid == thread.uid {
shouldNavigateToThreadList = true
}
}
}

private func didTapCell() {
Expand All @@ -101,7 +82,6 @@ struct ThreadListCell: View {
splitViewManager.splitViewController?.hide(.supplementary)
}
viewModel.selectedThread = thread
shouldNavigateToThreadList = true
}
}
}
Expand Down Expand Up @@ -132,6 +112,7 @@ struct ThreadListCell_Previews: PreviewProvider {
multipleSelectionViewModel: ThreadListMultipleSelectionViewModel(mailboxManager: PreviewHelper.sampleMailboxManager),
threadDensity: .large,
isSelected: false,
isMultiSelected: false,
editedMessageDraft: .constant(nil)
)
}
Expand Down
11 changes: 10 additions & 1 deletion Mail/Views/Thread List/ThreadListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ struct ThreadListView: View {

@EnvironmentObject var splitViewManager: SplitViewManager
@EnvironmentObject var globalBottomSheet: GlobalBottomSheet
@Environment(\.mailNavigationPath) private var path

@AppStorage(UserDefaults.shared.key(.threadDensity)) private var threadDensity = DefaultPreferences.threadDensity
@AppStorage(UserDefaults.shared.key(.accentColor)) private var accentColor = DefaultPreferences.accentColor
Expand Down Expand Up @@ -142,7 +143,8 @@ struct ThreadListView: View {
viewModel: viewModel,
multipleSelectionViewModel: multipleSelectionViewModel,
threadDensity: threadDensity,
isSelected: multipleSelectionViewModel.selectedItems
isSelected: viewModel.selectedThread?.uid == thread.uid,
isMultiSelected: multipleSelectionViewModel.selectedItems
.contains { $0.id == thread.id },
editedMessageDraft: $editedMessageDraft)
.id(thread.id)
Expand Down Expand Up @@ -232,6 +234,13 @@ struct ThreadListView: View {
.onChange(of: splitViewManager.selectedFolder) { newFolder in
changeFolder(newFolder: newFolder)
}
.onChange(of: viewModel.selectedThread) { newThread in
if let newThread {
path?.wrappedValue = [newThread]
} else {
path?.wrappedValue = []
}
}
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
updateFetchingTask()
}
Expand Down
17 changes: 10 additions & 7 deletions Mail/Views/Thread List/ThreadListViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,7 @@ class DateSection: Identifiable {
@Published var sections = [DateSection]()
@Published var selectedThread: Thread? {
didSet {
guard !isCompact, !filteredThreads.isEmpty else { return }
if selectedThread == nil, let index = selectedThreadIndex {
let realIndex = min(index, filteredThreads.count - 1)
selectedThread = filteredThreads[realIndex]
} else if let thread = selectedThread, let index = filteredThreads.firstIndex(where: { $0.uid == thread.uid }) {
selectedThreadIndex = index
}
selectedThreadIndex = filteredThreads.firstIndex { $0.uid == selectedThread?.uid }
}
}

Expand Down Expand Up @@ -238,6 +232,7 @@ class DateSection: Identifiable {
guard let newSections = self?.sortThreadsIntoSections(threads: filteredThreads) else { return }

DispatchQueue.main.sync {
self?.nextThreadIfNeeded(from: filteredThreads)
self?.filteredThreads = filteredThreads
if self?.filter != .all && filteredThreads.count == 1
&& self?.filter.accepts(thread: filteredThreads[0]) != true {
Expand All @@ -263,6 +258,14 @@ class DateSection: Identifiable {
}
}

func nextThreadIfNeeded(from threads: [Thread]) {
guard !isCompact,
!threads.contains(where: { $0.uid == selectedThread?.uid }),
let lastIndex = selectedThreadIndex else { return }
let validIndex = min(lastIndex, threads.count - 1)
selectedThread = threads[validIndex]
}

private func sortThreadsIntoSections(threads: [Thread]) -> [DateSection]? {
var newSections = [DateSection]()

Expand Down
26 changes: 13 additions & 13 deletions Mail/Views/Thread/ThreadView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ class MessageBottomSheet: DisplayedFloatingPanelState<MessageBottomSheet.State>

struct ThreadView: View {
@EnvironmentObject private var splitViewManager: SplitViewManager
@Environment(\.mailNavigationPath) private var path
@EnvironmentObject private var mailboxManager: MailboxManager

@ObservedRealmObject var thread: Thread
var onDismiss: (() -> Void)?

@State private var headerHeight: CGFloat = 0
@State private var displayNavigationTitle = false
Expand All @@ -58,9 +58,14 @@ struct ThreadView: View {

@EnvironmentObject var globalBottomSheet: GlobalBottomSheet
@EnvironmentObject var globalAlert: GlobalAlert
@Environment(\.verticalSizeClass) var sizeClass
@Environment(\.horizontalSizeClass) private var sizeClass
@Environment(\.verticalSizeClass) private var verticalSizeClass
@Environment(\.dismiss) var dismiss

var isCompact: Bool {
sizeClass == .compact || verticalSizeClass == .compact
}

@LazyInjectService private var matomo: MatomoUtils

private let toolbarActions: [Action] = [.reply, .forward, .archive, .delete]
Expand Down Expand Up @@ -176,19 +181,14 @@ struct ThreadView: View {
}
}
.onChange(of: thread.messages) { newMessagesList in
if newMessagesList.isEmpty {
showEmptyView = true
onDismiss?()
dismiss()
}
if thread.messageInFolderCount == 0 {
onDismiss?()
dismiss()
if newMessagesList.isEmpty || thread.messageInFolderCount == 0 {
if isCompact {
dismiss() // For iPhone
} else {
path?.wrappedValue = [] // For iPad
}
}
}
.emptyState(isEmpty: showEmptyView) {
EmptyStateView.emptyThread(from: splitViewManager.selectedFolder)
}
.matomoView(view: [MatomoUtils.View.threadView.displayName, "Main"])
}

Expand Down
2 changes: 2 additions & 0 deletions Project.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ let project = Project(name: "Mail",
.package(url: "https://github.com/kean/Nuke", .upToNextMajor(from: "12.0.0")),
.package(url: "https://github.com/airbnb/lottie-ios", .exact("3.5.0")),
.package(url: "https://github.com/scinfu/SwiftSoup", .upToNextMajor(from: "2.5.3")),
.package(url: "https://github.com/johnpatrickmorgan/NavigationBackport", .upToNextMajor(from: "0.7.2")),
.package(url: "https://github.com/aheze/Popovers", .upToNextMajor(from: "1.3.2"))
],
targets: [
Expand Down Expand Up @@ -79,6 +80,7 @@ let project = Project(name: "Mail",
.package(product: "WrappingHStack"),
.package(product: "FloatingPanel"),
.package(product: "Lottie"),
.package(product: "NavigationBackport"),
.package(product: "Popovers")
],
settings: .settings(base: baseSettings),
Expand Down

0 comments on commit 8a547ce

Please sign in to comment.