From 4120cff84c764231fa7035d6543a135fe2f06d52 Mon Sep 17 00:00:00 2001
From: Chris Offner <chrisoffner@pm.me>
Date: Thu, 25 Mar 2021 17:58:38 +0100
Subject: [PATCH] UI polish to MailListView and SearchView

---
 .../SwiftUI/Inbox/MailListView.swift          | 94 +++++++++----------
 .../SwiftUI/SupportingViews/SearchView.swift  | 48 +++++-----
 2 files changed, 66 insertions(+), 76 deletions(-)

diff --git a/enzevalos_iphone/SwiftUI/Inbox/MailListView.swift b/enzevalos_iphone/SwiftUI/Inbox/MailListView.swift
index 40013afb..62748290 100644
--- a/enzevalos_iphone/SwiftUI/Inbox/MailListView.swift
+++ b/enzevalos_iphone/SwiftUI/Inbox/MailListView.swift
@@ -15,64 +15,56 @@ struct MailListView: View {
     @Environment(\.managedObjectContext) var managedObjectContext
     var fetchRequest: FetchRequest<MailRecord>
     var mails: FetchedResults<MailRecord>{fetchRequest.wrappedValue}
+    var folderPath: String
+    var folderName: String
     
-    var folderpath: String
-    var name: String
-    
-    @State var updating = false
-    @State var showUser = false
-    @State var searchText = ""
-    @State var searchField = SearchType.All
-//    @State var searchNow = false
-    @State var composeMail = false
+    @State private var updating = false
+    @State private var showUser = false
+    @State private var searchText = ""
+    @State private var searchType = SearchType.All
+    @State private var composeMail = false
     
     init(folderpath: String, name: String) {
         fetchRequest = MailRecord.mailsInFolderFetchRequest(folderpath: folderpath)
-        self.folderpath = folderpath
-        self.name = name
-    }
-    var body: some View {
-        mainView
-            .navigationBarTitle(name, displayMode: .inline)
-            .onAppear {
-                self.updateMails()
-            }
-            .sheet(isPresented: $composeMail) {
-                ComposeView()
-            }
+        self.folderPath = folderpath
+        self.folderName = name
     }
     
-    private var mainView: some View {
-        VStack (alignment: .leading){
-            SearchView(searchText: $searchText, searchType: $searchField)
-                .padding(6)
-            mailList
-                .padding(-12)
-            // Toolbar
-            HStack {
-                Spacer()
-                self.lastUpdate
-                Spacer()
-                self.composeButton
-            }
-            .padding(6)
+    var body: some View {
+        VStack(alignment: .leading) {
+            SearchView(searchText: $searchText, searchType: $searchType).padding()
+            
+            mailList.padding(-12)
         }
+            .navigationBarTitle(folderName, displayMode: .inline)
+            .onAppear { updateMails() }
+            .sheet(isPresented: $composeMail) { ComposeView() }
+            .toolbar {
+                ToolbarItem(placement: .status) {
+                    lastUpdate
+                }
+                
+                ToolbarItemGroup(placement: .bottomBar) {
+                    Spacer()
+                    composeButton
+                }
+            }
     }
     
     private var mailList: some View {
-        List (self.mails.filter(filterKeyRecord), id: \.self) { record in
-            NavigationLink(
-                destination: ReadMainView(model: ReadModel(mail: record))) {
+        List(self.mails.filter(filterKeyRecord), id: \.self) { record in
+            NavigationLink(destination: ReadMainView(model: ReadModel(mail: record))) {
                 MailRowView(mail: record)
             }
         }
+        .listStyle(InsetGroupedListStyle())
         .resignKeyboardOnDragGesture() // hide keyboard when dragging
     }
     
     private var composeButton: some View {
-        Button(action: {
+        Button {
             composeMail = true
-        }) {
+        } label: {
             Image(systemName: "square.and.pencil").imageScale(.large)
         }
     }
@@ -89,7 +81,7 @@ struct MailListView: View {
             text = NSLocalizedString("LastUpdate", comment: "") + " " + dateString
         }
         
-        return Button(action: updateMails)  {
+        return Button(action: updateMails) {
             Text(text)
                 .font(.callout)
         }
@@ -99,22 +91,20 @@ struct MailListView: View {
         guard !updating else {
             return
         }
+        
         LetterboxModel
             .instance
             .mailHandler
-            .updateFolder(folderpath: folderpath,
-                          completionCallback: { error in
-                            if error == nil {
-                                self.updating = false
-                            }
-                            // TODO: Add error message
-                          })
+            .updateFolder(folderpath: folderPath) { error in
+                if error == nil {
+                    self.updating = false
+                }
+                // TODO: Add error message
+            }
         updating = true
     }
     
     func filterKeyRecord(keyRecord: MailRecord) -> Bool {
-//        let searchType = SearchType.findType(i: searchField)
-        let searchType = searchField
         if self.searchText.isEmpty
             || self.searchText == NSLocalizedString("Searchbar.Title", comment: "Search") {
             return true
@@ -127,8 +117,8 @@ struct MailListView: View {
             return true
         } else if (searchType == .All || searchType == .Sender)
                     && keyRecord.addresses.filter({
-            containsSearchTerms(content: $0.email,
-                                searchText: query) }).count > 0 {
+                                                    containsSearchTerms(content: $0.email,
+                                                                        searchText: query) }).count > 0 {
             return true
         } else if (searchType == .All || searchType == .Subject)
                     && containsSearchTerms(content: keyRecord.subject, searchText: query) {
diff --git a/enzevalos_iphone/SwiftUI/SupportingViews/SearchView.swift b/enzevalos_iphone/SwiftUI/SupportingViews/SearchView.swift
index 4bc454a6..57dc3e76 100644
--- a/enzevalos_iphone/SwiftUI/SupportingViews/SearchView.swift
+++ b/enzevalos_iphone/SwiftUI/SupportingViews/SearchView.swift
@@ -9,70 +9,60 @@
 import SwiftUI
 import Combine
 
-/**
- Where are we looking for? Used in the search footer.
- */
-enum SearchType: LocalizedStringKey, CaseIterable {
-    case All = "All"
-    case Sender = "Sender"
-    case Subject = "Subject"
-    case Body = "Body"
-}
 /**
  A SearchView for mails with a search segmented Picker to choose the search area.
  Open Problems: Deplay the search, s.t. we do not start a search after each input.
- 
  */
 struct SearchView: View {
     @Binding var searchText: String
     @Binding var searchType: SearchType
-    @State private var showCancelButton: Bool = false
+    @State private var editingSearchField: Bool = false
     
     var body: some View {
         VStack {
             HStack {
                 searchFieldView
-                if showCancelButton {
+                if editingSearchField {
                     Button("Cancel") {
                         UIApplication.shared.endEditing(true)
-                        self.searchText = ""
-                        self.showCancelButton = false
+                        searchText = ""
                     }
-                    .foregroundColor(Color(.systemBlue))
+                    .foregroundColor(.accentColor)
                 }
             }
             
-            if showCancelButton {
+            if editingSearchField {
                 searchTypePicker
             }
         }
-        .padding(.horizontal)
     }
     
     var searchFieldView: some View {
         HStack {
             Image(systemName: "magnifyingglass")
-            TextField(NSLocalizedString("Searchbar.Title", comment: "Search"),
-                      text: $searchText) { _ in
-                self.showCancelButton = true
+            
+            TextField("Searchbar.Title", text: $searchText) { isEditing in
+                withAnimation {
+                    editingSearchField = isEditing
+                }
             }
             .foregroundColor(.primary)
             
             Button {
-                self.searchText = ""
+                searchText = ""
             } label: {
                 Image(systemName: "xmark.circle.fill")
                     .opacity(searchText == "" ? 0 : 1)
             }
         }
-        .padding(EdgeInsets(top: 8, leading: 6, bottom: 8, trailing: 6))
+        .padding(8)
         .foregroundColor(.secondary)
         .background(Color(.secondarySystemBackground))
         .cornerRadius(10.0)
     }
     
     var searchTypePicker: some View {
-        Picker("Hellooo", selection: $searchType) {
+        Picker("Search Filter", selection: $searchType) {
             ForEach(SearchType.allCases, id: \.self) { searchType in
                 Text(searchType.rawValue)
             }
@@ -88,7 +78,7 @@ struct SearchView: View {
 extension UIApplication {
     func endEditing(_ force: Bool) {
         self.windows
-            .filter{$0.isKeyWindow}
+            .filter { $0.isKeyWindow }
             .first?
             .endEditing(force)
     }
@@ -108,3 +98,13 @@ extension View {
         return modifier(ResignKeyboardOnDragGesture())
     }
 }
+
+/**
+ Where are we looking for? Used in the search footer.
+ */
+enum SearchType: LocalizedStringKey, CaseIterable {
+    case All = "All"
+    case Sender = "Sender"
+    case Subject = "Subject"
+    case Body = "Body"
+}
-- 
GitLab