Skip to content
Snippets Groups Projects
Commit 662cdf94 authored by cruxfilm's avatar cruxfilm
Browse files

Simplified RecipientType enum,

added attribution,
code style improvements
parent c3d26916
No related branches found
No related tags found
1 merge request!76Resolve "InboxView & MailListView improvements"
......@@ -2,7 +2,7 @@
// ComposeHeaderView.swift
// enzevalos_iphone
//
// Created by Chris Offner on 23.03.21.
// Created by Chris Offner & Claire Bräuer on 23.03.21.
// Copyright © 2021 fu-berlin. All rights reserved.
//
......@@ -12,35 +12,29 @@ import SwiftUI
struct ComposeViewHeader: View {
@Environment(\.presentationMode) var presentationMode
@ObservedObject var model: ComposeModel
@State private var encryptionOn = true
var body: some View {
VStack {
// Grab handle in top center
Capsule()
.fill(Color(.lightGray))
.frame(width: 70, height: 5)
ZStack {
HStack {
// Cancel button
Button("Cancel") {
presentationMode.wrappedValue.dismiss()
}
Spacer()
Button("Send") {
model.sendMail()
presentationMode.wrappedValue.dismiss()
}
.disabled(model.recipientsModel.hasNoRecipients)
ZStack {
HStack {
// Cancel button
Button("Cancel") {
presentationMode.wrappedValue.dismiss()
}
Toggle("", isOn: $encryptionOn)
.toggleStyle(EncryptionToggleStyle())
.labelsHidden()
Spacer()
// Send button, disabled if no recipients are set.
Button("Send") {
model.sendMail()
presentationMode.wrappedValue.dismiss()
}
.disabled(model.recipientsModel.hasNoRecipients)
}
// Encryption toggle
Toggle("", isOn: $model.encryptionOn)
.toggleStyle(EncryptionToggleStyle())
.labelsHidden()
}
}
......@@ -65,7 +59,7 @@ struct ComposeViewHeader: View {
ZStack {
Circle()
.stroke(Color.blue, lineWidth: 2)
Image(systemName: "lock.fill")
.font(Font.system(size: 24, weight: Font.Weight.light))
.foregroundColor(.blue)
......
......@@ -3,6 +3,7 @@
// enzevalos_iphone
//
// Created by Oliver Wiese on 12.11.20.
// modified by Chris Offner & Claire Bräuer in March 2021
// Copyright © 2020 fu-berlin. All rights reserved.
//
......@@ -12,7 +13,7 @@ import Foundation
class ComposeModel: ObservableObject {
@Published var subject = ""
@Published var body = ""
@Published var encryptionOff = false
@Published var encryptionOn = true
@Published var recipientsModel: RecipientsModel = RecipientsModel()
init(preData: PreMailData?) {
......@@ -26,7 +27,7 @@ class ComposeModel: ObservableObject {
recipientsModel.parentComposeModel = self
}
// TODO: Add security state
// TODO: Add security state functionality
/// Generates mail and sends it.
func sendMail() {
......@@ -55,7 +56,7 @@ class ComposeModel: ObservableObject {
textContent: body,
htmlContent: nil,
textparts: 1,
sendEncryptedIfPossible: !encryptionOff,
sendEncryptedIfPossible: encryptionOn,
attachments: [])
}
}
......@@ -53,14 +53,14 @@ struct ComposeView: View {
/// A view in which recipients get added or removed.
struct RecipientField: View {
@ObservedObject var model: RecipientFieldModel
@State var showList = false
@State var indexOfSelected: Int?
@State private var showList = false
@State private var indexOfSelected: Int?
var body: some View {
VStack {
HStack {
// Recipient text field
Text(model.type.asString)
Text(model.type.rawValue)
.foregroundColor(Color(UIColor.tertiaryLabel))
// Selected recipients as blue capsules,
......@@ -125,8 +125,8 @@ struct RecipientField: View {
// capsule in the ForEach loop above. 🤔🤔🤔
print(model.selectedContacts.count)
}
.frame(minWidth: 200)
.autocapitalization(.none)
.frame(width: 200) // TODO: Stretch dynamically over available horizontal space
.autocapitalization(.none) // .frame(maxWidth: .infinity) somehow doesn't work
.keyboardType(.emailAddress)
}
}
......@@ -166,11 +166,11 @@ struct RecipientCapsule: View {
Text(name)
.fixedSize(horizontal: true, vertical: false)
// Deletion button shown if recipient capsule is selected
// Remove button shown if recipient capsule is selected
if isSelected {
Button(action: removeRecipient) {
Image(systemName: "xmark")
}
} // Transition: Slide in from left, slide out to left
.transition(.asymmetric(
insertion: AnyTransition
.opacity.combined(with: .slide),
......@@ -179,8 +179,7 @@ struct RecipientCapsule: View {
)
}
}
.padding(.horizontal, 8)
.padding(.vertical, 2)
.padding(EdgeInsets(top: 2, leading: 8, bottom: 2, trailing: 8))
.foregroundColor(isSelected ? .accentColor : .secondary)
}
}
......@@ -191,6 +190,7 @@ struct RecipientCapsule: View {
recipient.displayname ?? recipient.email.components(separatedBy: "@")[0]
}
/// Removes recipient from selected contacts of respective RecipientFieldModel.
func removeRecipient() {
if let index = model.selectedContacts.firstIndex(of: recipient) {
model.deselectContact(at: index)
......
......@@ -2,7 +2,8 @@
// TokenFieldModel.swift
// enzevalos_iphone
//
// Created by Oliver Wiese on 31.10.20.
// Created by Oliver Wiese on 31.10.20,
// modified by Chris Offner & Claire Bräuer in March 2021
// Copyright © 2020 fu-berlin. All rights reserved.
//
......@@ -14,16 +15,16 @@ class RecipientFieldModel: ObservableObject {
@Published var suggestions = [AddressRecord]()
@Published var selectedContacts = [AddressRecord]()
@Published var type: RecipientType
private var dataprovider: PersistentDataProvider
private var dataprovider: PersistentDataProvider = LetterboxModel.instance.dataProvider
var parentRecipientModel: RecipientsModel?
init(type: RecipientType, dataprovider: PersistentDataProvider) {
init(type: RecipientType) {
self.type = type
self.dataprovider = dataprovider
}
@Published var text = "" {
didSet {
// Split entered text at separator characters, add first part as address
if text.contains(" ") || text.contains(",") || text.contains(";") {
var firstWord = text.split(separator: "\n").first
firstWord?.removeLast()
......@@ -33,18 +34,15 @@ class RecipientFieldModel: ObservableObject {
text = ""
}
// TODO: Show suggestions in ComposeView.
// Generate suggestions based on entered text.
if !text.isEmpty {
let frc = dataprovider
.createFetchResultController(
// Fetch addresses that match entered prefix.
let frc = dataprovider.createFetchResultController(
fetchRequest: AddressRecord.lookForPrefix(prefix: text)
)
if let addresses = frc.fetchedObjects {
suggestions = addresses
} else {
suggestions = []
}
// Set addresses as suggestions if any were found, otherwise empty suggestions
suggestions = frc.fetchedObjects ?? []
} else {
suggestions = []
}
......@@ -60,23 +58,18 @@ class RecipientFieldModel: ObservableObject {
return suggestions
}
let frc = LetterboxModel
.instance
.dataProvider
.createFetchResultController(
fetchRequest: AddressRecord
.all(sortBy: sortBy)
)
let frc = LetterboxModel.instance.dataProvider.createFetchResultController(
fetchRequest: AddressRecord.all(sortBy: sortBy)
)
if let addresses = frc.fetchedObjects {
return addresses
}
return []
return frc.fetchedObjects ?? []
}
/// Adds contact at index to recipients.
func selectContact(addr: AddressRecord) {
selectedContacts.append(addr)
/// Adds AddressRecord of a contact to array of recipients.
///
/// - Parameter _: AddressRecord that gets added to array of recipients.
func selectContact(_ addressRecord: AddressRecord) {
selectedContacts.append(addressRecord)
text = ""
suggestions = []
......@@ -89,12 +82,12 @@ class RecipientFieldModel: ObservableObject {
}
/// Removes contact at index from recipients.
///
/// - Parameter at: Index of contact to be removed from array of recipients.
func deselectContact(at index: Int) {
if index < selectedContacts.count {
selectedContacts.remove(at: index)
} else {
print("ERROR wrong index! \(index) but \(selectedContacts.count)")
}
selectedContacts.remove(at: index)
// TODO: See TODO in selectContact.
parentRecipientModel?.parentComposeModel?.subject += ""
}
......@@ -104,12 +97,17 @@ class RecipientFieldModel: ObservableObject {
addNewAddress(text)
text = ""
}
// TODO: See TODO in selectContact.
parentRecipientModel?.parentComposeModel?.subject += ""
}
/// Adds new address to selected contacts.
///
/// - Parameter _: Email address string to be added.
func addNewAddress(_ address: String) {
guard address.count > 0 && address.contains("@") else {
// TODO: Add email validation + warning?
// TODO: Add proper email validation + warning
return
}
......
......@@ -10,7 +10,7 @@ import SwiftUI
/// A view that lists contacts for selection as recipients.
struct RecipientListView: View {
@EnvironmentObject var model: RecipientFieldModel
@State var sortByName = true
@State private var sortByName = true
var body: some View {
VStack(alignment: .leading) {
......
......@@ -17,7 +17,7 @@ struct RecipientRowView: View {
if let index = model.selectedContacts.firstIndex(where: { $0.email == contact.email }) {
model.deselectContact(at: index)
} else {
model.selectContact(addr: contact)
model.selectContact(contact)
}
} label: {
HStack {
......
......@@ -3,6 +3,7 @@
// enzevalos_iphone
//
// Created by Oliver Wiese on 09.11.20.
// modified by Chris Offner & Claire Bräuer in March 2021
// Copyright © 2020 fu-berlin. All rights reserved.
//
......@@ -10,27 +11,6 @@ import Foundation
import Combine
import SwiftUI
/// Type of recipient field (to, cc, bcc).
enum RecipientType {
case to
case cc
case bcc
case ccBcc
var asString: LocalizedStringKey {
switch self {
case .to:
return "To"
case .cc:
return "Cc"
case .bcc:
return "Bcc"
case .ccBcc:
return "CcBcc"
}
}
}
/// Holds models for "To", "Cc", and "Bcc" fields.
class RecipientsModel: ObservableObject {
let toModel: RecipientFieldModel
......@@ -41,10 +21,9 @@ class RecipientsModel: ObservableObject {
/// Initializes models for "To", "Cc", and "Bcc" fields.
init() {
let dataprovider = LetterboxModel.instance.dataProvider
toModel = RecipientFieldModel(type: .to, dataprovider: dataprovider)
ccModel = RecipientFieldModel(type: .ccBcc, dataprovider: dataprovider)
bccModel = RecipientFieldModel(type: .bcc, dataprovider: dataprovider)
toModel = RecipientFieldModel(type: .to)
ccModel = RecipientFieldModel(type: .ccBcc)
bccModel = RecipientFieldModel(type: .bcc)
toModel.parentRecipientModel = self
ccModel.parentRecipientModel = self
bccModel.parentRecipientModel = self
......@@ -69,21 +48,27 @@ class RecipientsModel: ObservableObject {
/// String array of email addresses in "To" field.
var toEMails: [String] {
get {
toModel.selectedContacts.map({ $0.email })
toModel.selectedContacts.map {
$0.email
}
}
}
/// String array of email addresses in "Cc" field.
var ccEMails: [String] {
get {
ccModel.selectedContacts.map({ $0.email })
ccModel.selectedContacts.map {
$0.email
}
}
}
/// String array of email addresses in "Bcc" field.
var bccEMails: [String] {
get {
bccModel.selectedContacts.map({ $0.email })
bccModel.selectedContacts.map {
$0.email
}
}
}
......@@ -95,3 +80,11 @@ class RecipientsModel: ObservableObject {
ccModel.type = showBccField ? .cc : .ccBcc
}
}
/// Type of recipient field (to, cc, bcc).
enum RecipientType: LocalizedStringKey {
case to = "To"
case cc = "Cc"
case bcc = "Bcc"
case ccBcc = "CcBcc"
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment