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