From 5b5618eed1a855b8d906876c53ce1a9224e064c1 Mon Sep 17 00:00:00 2001
From: Oliver Wiese <oliver.wiese@fu-berlin.de>
Date: Mon, 6 Apr 2020 16:59:26 +0200
Subject: [PATCH] improve ReadViewSender

---
 enzevalos_iphone.xcodeproj/project.pbxproj    |   4 +
 .../KeyRecord+CoreDataProperties.swift        |  14 +-
 .../PersistentMail +CoreDataProperties.swift  |  19 +-
 .../SwiftUI/Read/ReadMainView.swift           |   2 +-
 .../SwiftUI/Read/ReadViewCoordinator.swift    |   9 +
 .../SwiftUI/Read/ReadViewModel.swift          |  16 +-
 .../SwiftUI/Read/SenderViewMain.swift         | 254 ++++++++----------
 .../SmallContactListView.swift                |  80 ++++++
 enzevalos_iphone/de.lproj/Localizable.strings |   2 +
 enzevalos_iphone/en.lproj/Localizable.strings |   2 +
 10 files changed, 242 insertions(+), 160 deletions(-)
 create mode 100644 enzevalos_iphone/SwiftUI/Read/Tabbed Views/SenderViewChildren/SmallContactListView.swift

diff --git a/enzevalos_iphone.xcodeproj/project.pbxproj b/enzevalos_iphone.xcodeproj/project.pbxproj
index adb25158..42161f51 100644
--- a/enzevalos_iphone.xcodeproj/project.pbxproj
+++ b/enzevalos_iphone.xcodeproj/project.pbxproj
@@ -141,6 +141,7 @@
 		47A5D6E42294BFF50084F81D /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47A5D6E32294BFF50084F81D /* Logger.swift */; };
 		47C036FF2347C0F5006295E8 /* ImportKeyOverviewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47C036FE2347C0F4006295E8 /* ImportKeyOverviewController.swift */; };
 		47C037032347D4D1006295E8 /* PasteKeyViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47C037022347D4D1006295E8 /* PasteKeyViewController.swift */; };
+		47C09C76243B3395007F74A2 /* SmallContactListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47C09C75243B3395007F74A2 /* SmallContactListView.swift */; };
 		47C22281218AFD6300BD2C2B /* AutocryptTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47C22280218AFD6300BD2C2B /* AutocryptTest.swift */; };
 		47C22283218B02C700BD2C2B /* autocryptSimpleExample1.eml in Resources */ = {isa = PBXBuildFile; fileRef = 47C22282218B02C700BD2C2B /* autocryptSimpleExample1.eml */; };
 		47C8225324379EAE005BCE73 /* AttachmentsViewMain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47C8224324379EAE005BCE73 /* AttachmentsViewMain.swift */; };
@@ -587,6 +588,7 @@
 		47B2318A1F0D458100961B28 /* enzevalos_iphone 2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "enzevalos_iphone 2.xcdatamodel"; sourceTree = "<group>"; };
 		47C036FE2347C0F4006295E8 /* ImportKeyOverviewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportKeyOverviewController.swift; sourceTree = "<group>"; };
 		47C037022347D4D1006295E8 /* PasteKeyViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasteKeyViewController.swift; sourceTree = "<group>"; };
+		47C09C75243B3395007F74A2 /* SmallContactListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmallContactListView.swift; sourceTree = "<group>"; };
 		47C22280218AFD6300BD2C2B /* AutocryptTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutocryptTest.swift; sourceTree = "<group>"; };
 		47C22282218B02C700BD2C2B /* autocryptSimpleExample1.eml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = autocryptSimpleExample1.eml; sourceTree = "<group>"; };
 		47C8224324379EAE005BCE73 /* AttachmentsViewMain.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AttachmentsViewMain.swift; sourceTree = "<group>"; };
@@ -1299,6 +1301,7 @@
 			children = (
 				47C822672438A85C005BCE73 /* PhishingView.swift */,
 				47C822662438A85C005BCE73 /* SenderDetails.swift */,
+				47C09C75243B3395007F74A2 /* SmallContactListView.swift */,
 			);
 			path = SenderViewChildren;
 			sourceTree = "<group>";
@@ -2222,6 +2225,7 @@
 				472F39861E1FA34E009260FB /* Record.swift in Sources */,
 				A1C3270E1DB907D900CE2ED5 /* TextFormatter.swift in Sources */,
 				F12041FD1DA409A5002E4940 /* ListViewCell.swift in Sources */,
+				47C09C76243B3395007F74A2 /* SmallContactListView.swift in Sources */,
 				A1EFF93321E6655C003BB240 /* IntroTableView.swift in Sources */,
 				47EABF272423BFDD00774A93 /* AuthenticationScreen.swift in Sources */,
 				4764069A2416B54D00C7D426 /* MailView.swift in Sources */,
diff --git a/enzevalos_iphone/KeyRecord+CoreDataProperties.swift b/enzevalos_iphone/KeyRecord+CoreDataProperties.swift
index b4a2b9b6..a0471107 100644
--- a/enzevalos_iphone/KeyRecord+CoreDataProperties.swift
+++ b/enzevalos_iphone/KeyRecord+CoreDataProperties.swift
@@ -113,6 +113,18 @@ extension KeyRecord{
 }
 
 extension KeyRecord: DisplayContact {
+    var previousMails: Int {
+        return self.persistentMails?.count ?? 0
+    }
+    
+    var previousResponses: Int {
+        return -1
+    }
+    
+    var keyRecord: KeyRecord? {
+        return self
+    }
+    
     var addr: String {
         return self.addresses.first?.mailAddress ?? "No address"
     }
@@ -147,6 +159,4 @@ extension KeyRecord: DisplayContact {
     var similarContacts: [String] {
         return [] // TODO!
     }
-    
-    
 }
diff --git a/enzevalos_iphone/PersistentMail +CoreDataProperties.swift b/enzevalos_iphone/PersistentMail +CoreDataProperties.swift
index 6a41e619..ae53598b 100644
--- a/enzevalos_iphone/PersistentMail +CoreDataProperties.swift	
+++ b/enzevalos_iphone/PersistentMail +CoreDataProperties.swift	
@@ -420,17 +420,22 @@ extension PersistentMail {
 
 
 extension PersistentMail: DisplayMail {
+    typealias C = KeyRecord
     
-    var sender: DisplayContact {
+    var sender: C {
         return self.record!
     }
     
-    var ccs: [DisplayContact] {
-        return [] // TODO
+    var tos: [C] {
+        return [self.record!,self.record!,self.record!]
     }
     
-    var bccs: [DisplayContact] {
-        return [] // TODO
+    var ccs: [C] {
+        return [self.record!,self.record!,self.record!] // TODO
+    }
+    
+    var bccs: [C] {
+        return [self.record!,self.record!,self.record!] // TODO
     }
     
     var routingStops: [Landmark] {
@@ -441,5 +446,9 @@ extension PersistentMail: DisplayMail {
         return self.sigState
     }
     
+    var persistentMail: PersistentMail? {
+        return self
+    }
+    
     
 }
diff --git a/enzevalos_iphone/SwiftUI/Read/ReadMainView.swift b/enzevalos_iphone/SwiftUI/Read/ReadMainView.swift
index cb1b7eef..2b9c3512 100644
--- a/enzevalos_iphone/SwiftUI/Read/ReadMainView.swift
+++ b/enzevalos_iphone/SwiftUI/Read/ReadMainView.swift
@@ -56,7 +56,7 @@ struct ReadMainView: View {
                 Tab(
                     image: Image(systemName: "person.fill"),
                     description: "sender",
-                    content: AnyView(SenderViewMain(mail: mail))
+                    content: AnyView(SenderViewMain<PersistentMail, KeyRecord>(mail: mail))
                 ),
                 Tab(
                     image: Image(systemName: "text.bubble.fill"),
diff --git a/enzevalos_iphone/SwiftUI/Read/ReadViewCoordinator.swift b/enzevalos_iphone/SwiftUI/Read/ReadViewCoordinator.swift
index 646a591c..a0fd4bb4 100644
--- a/enzevalos_iphone/SwiftUI/Read/ReadViewCoordinator.swift
+++ b/enzevalos_iphone/SwiftUI/Read/ReadViewCoordinator.swift
@@ -81,6 +81,15 @@ class ReadViewCoordinator {
         root.pushViewController(vc, animated: true)
     }
     
+    func pushContactView(contact: KeyRecord) {
+        let vc = mainStoryboard.instantiateViewController(withIdentifier: ViewID.KeyRecordView.rawValue)
+        if let vc = vc as? ContactViewController {
+           vc.keyRecord = contact
+        }
+        root.isToolbarHidden = false
+        root.pushViewController(vc, animated: true)
+    }
+        
     func shareData(_ data:NSData){
         //let shareText = "Hello, world!"
         
diff --git a/enzevalos_iphone/SwiftUI/Read/ReadViewModel.swift b/enzevalos_iphone/SwiftUI/Read/ReadViewModel.swift
index ce942161..70855afa 100644
--- a/enzevalos_iphone/SwiftUI/Read/ReadViewModel.swift
+++ b/enzevalos_iphone/SwiftUI/Read/ReadViewModel.swift
@@ -21,23 +21,31 @@ protocol DisplayContact {
     var keys: [String] { get }
     
     // Phishing related
-    var hasPreviousMails: Bool { get }
+    var previousMails: Int { get }
+    var previousResponses: Int { get }
     var hasSimilarContacts: Bool { get }
     var similarContacts: [String] { get }
+
+    var keyRecord: KeyRecord? { get }
 }
 
 
 protocol DisplayMail {
+    associatedtype C: DisplayContact
+    
     var subject: String? { get }
     var body: String? { get }
-    var sender: DisplayContact { get }
-    var ccs: [DisplayContact] { get }
-    var bccs: [DisplayContact] { get }
+    var sender: C { get }
+    var tos: [C] { get }
+    var ccs: [C] { get }
+    var bccs: [C] { get }
     var routingStops: [Landmark] { get }
     
     // Crypto
     var signedState: SignatureState { get }
     var encState: EncryptionState { get }
+    
+    var persistentMail: PersistentMail? { get }
 }
 class ReadViewModel: ObservableObject {
     
diff --git a/enzevalos_iphone/SwiftUI/Read/SenderViewMain.swift b/enzevalos_iphone/SwiftUI/Read/SenderViewMain.swift
index f7277e49..d90a48a0 100644
--- a/enzevalos_iphone/SwiftUI/Read/SenderViewMain.swift
+++ b/enzevalos_iphone/SwiftUI/Read/SenderViewMain.swift
@@ -22,122 +22,31 @@
 import SwiftUI
 import CoreLocation
 
-struct SenderViewMain: View {
+struct SenderViewMain <M: DisplayMail, C: DisplayContact>: View {
     
-    let mail: DisplayMail
+    let mail: M
     
     @State var selectedLandmark: Landmark? = nil
     @State var showingLandmarkDetails = false
     
     
     var body: some View {
-        VStack {
-            ZStack {
-                ZStack {
-                    MapView(landmarks: mail.routingStops,
-                            selectedLandmark: $selectedLandmark,  showingLandmarkDetails: $showingLandmarkDetails)
-                        .frame(height: 300)
-                    HStack {
-                        Button(action: {
-                            /// this button displays the previous selected landmark
-                            self.selectPrevLandmark()
-                        }) {
-                            Text("prev")
-                                .foregroundColor(.black)
-                                .padding()
-                                .background(Color.white)
-                                .cornerRadius(6)
-                                .shadow(radius: 3)
-                                .padding(.top, 150)
-                        }
-                        
-                        Spacer()
-                        Button(action: {
-                            /// this button displays the next selected landmark
-                            self.selectNextLandmark()
-                        }) {
-                            Text("Next")
-                                .foregroundColor(.black)
-                                .padding()
-                                .background(Color.white)
-                                .cornerRadius(6)
-                                .shadow(radius: 3)
-                                .padding(.top, 150)
-                        }
-                    }
-                } .alert(isPresented: $showingLandmarkDetails) {
-                    /// alert displays the landmark details and gets trigered when the user taps the information button of a landmark
-                    Alert(title: Text("Domain for this location"), message: Text(selectedLandmark?.domain ?? "Missing place information"), dismissButton: .default(Text("OK")) )
-                        }
-            }
+        ScrollView {
+            map
             icon
-                    //TODO: make toucarea clip to circle .clipShape(Circle()
-            ZStack {
-            
-                VStack(alignment: .leading) {                    
-                    SenderDetails()
-                    Divider()
-                    VStack (alignment: .leading){
-    
-                            HStack{
-                            
-                            Text("CC:")
-                                //// the CC emails are displayed only when they exist
-                              .font(.subheadline)
-                              .padding(.bottom, 20)
-                       
-                                if mail.ccs.count == 0 {
-                                   Text("-")
-                               }else{
-                                ScrollView(.vertical){
-                                    
-                                    ForEach(0..<mail.ccs.count) { i in
-                                        Text(self.mail.ccs[i].name)
-                                     }
-                                    
-                                }.frame(height: 30)
-                                  
-                                 .padding(.bottom, 10)
-                                
-                             }
-                            
-                            }.font(.system(size: 12))
-                        
-                    }
-                    
-                    if mail.bccs.count > 0 {
-                        /// the whole BCC section is displayed only when BCC emails exist
-                        Divider()
-                        VStack (alignment: .leading){
-                            HStack (spacing: 20){
-                                Text("BCC:")
-                                 .font(.subheadline)
-                                 .padding(.bottom, 8)
-                                
-                                ScrollView (.vertical){
-                                
-                                    ForEach(0..<mail.bccs.count) { i in
-                                        Text(self.mail.bccs[i].name)
-                                    }
-                                    
-                                }.frame(height: 30)
-                                .padding(.bottom, 10)
-                                
-                            }.font(.system(size: 12))
-                            
-                        }
-                    }
-                    Divider()
-                    DropDown()
-                    Spacer()
-                    
-                }.padding()
-                Spacer()
-            }
-            Spacer()
+            sender
+                .offset(y: (-110/2 + 5))
+            Divider()
+            SmallContactListView(contacts: mail.tos, title: NSLocalizedString("To", comment: "To"))
+            Divider()
+            SmallContactListView(contacts: mail.ccs, title: NSLocalizedString("Cc", comment: "CC"))
+            Divider()
+            SmallContactListView(contacts: mail.bccs, title: NSLocalizedString("Bcc", comment: "BCC"))
         }
     }
     
+    
+    
     private func selectNextLandmark() {
         let landmarks = mail.routingStops
         /// This method identifies and moves to the next selected landmark
@@ -168,48 +77,80 @@ struct SenderViewMain: View {
             .offset(y: -110/2)
             .padding(.bottom, -110/2)
             .onTapGesture {
-                    //Goto contact view
+                self.goToContact(contact: self.mail.sender)
             }
     }
-}
-
-
-
-
-// important TODO: add phishing elements
-struct DropDown: View {
-    /// Displays the phishing details in a drop down window
-    @State private var clicked = false
-    var body: some View {
-        VStack (alignment: .leading, spacing: 20) {
-            
-            HStack(alignment: .top) {
-                Text("Phishing:")
-                    .font(.subheadline)
-                
-                Button (action: {
-                    self.clicked.toggle()
-                }) {
-                    
-                    Image(systemName: clicked ? "chevron.up" : "chevron.down")
+    
+    private var sender: some View {
+        VStack (alignment: .leading, spacing: 10) {
+            Button(action: {self.goToContact(contact: self.mail.sender)}) {
+                VStack (alignment: .leading) {
+                    Text(NSLocalizedString("Sender", comment: "Sender"))
+                            .font(.headline)
+                    Text(mail.sender.name)
+                            .font(.subheadline)
+                    Text(mail.sender.addr)
+                       // .foregroundColor(.gray)
+                    //TODO: Add last mail date
                 }
             }
-                            
-                if clicked {
-                    
-                    HStack {
-                        
-                        Spacer()
-                            .frame(width: 70)
-                        
-                        PhishingView()
-                        .font(.system(size: 12))
+            HStack{
+                Text(String(format: NSLocalizedString("ReadView.Sender.Previous", comment: "100 previous received mails"), mail.sender.previousMails))
+                    Spacer()
+                 Text(String(format: NSLocalizedString("ReadView.Sender.Responses", comment: "5 previous sent mails"), mail.sender.previousResponses))
+            }
+        }
+    .padding(10)
+    }
+    
+    private var map: some View {
+        ZStack {
+            ZStack {
+                MapView(landmarks: mail.routingStops,
+                        selectedLandmark: $selectedLandmark,  showingLandmarkDetails: $showingLandmarkDetails)
+                    .frame(height: 300)
+                HStack {
+                    Button(action: {
+                        /// this button displays the previous selected landmark
+                        self.selectPrevLandmark()
+                    }) {
+                        Text("prev")
+                            .foregroundColor(.black)
+                            .padding()
+                            .background(Color.white)
+                            .cornerRadius(6)
+                            .shadow(radius: 3)
+                            .padding(.top, 150)
                     }
-                
                     
+                    Spacer()
+                    Button(action: {
+                        /// this button displays the next selected landmark
+                        self.selectNextLandmark()
+                    }) {
+                        Text("Next")
+                            .foregroundColor(.black)
+                            .padding()
+                            .background(Color.white)
+                            .cornerRadius(6)
+                            .shadow(radius: 3)
+                            .padding(.top, 150)
+                    }
                 }
-        }.padding([.top, .bottom], 5)
-  }
+            } .alert(isPresented: $showingLandmarkDetails) {
+                /// alert displays the landmark details and gets trigered when the user taps the information button of a landmark
+                Alert(title: Text("Domain for this location"), message: Text(selectedLandmark?.domain ?? "Missing place information"), dismissButton: .default(Text("OK")) )
+                    }
+        }
+    }
+    
+    private func goToContact(contact: DisplayContact) {
+        guard let con = contact.keyRecord else {
+            print("No record...")
+            return
+        }
+        AppDelegate.getAppDelegate().readViewCoordinator?.pushContactView(contact: con)
+    }
 }
 
 struct SenderView_Previews: PreviewProvider {
@@ -222,22 +163,30 @@ struct SenderView_Previews: PreviewProvider {
               // "iPad Pro (11-inch)"
            ]
            
-        let sender = PseudoContact(name: "Alice", addr: "alice@example.com", myImage: PseudoContact.makeImageFromName("Alice", color: .blue))
+        let sender = PseudoContact(name: "Alice", addr: "alice@example.com", myImage: PseudoContact.makeImg("Alice", color: .blue))
+        let bob = PseudoContact(name: "Bob", addr: "Bob.lord.of.kingsbridge.and.king.of.england@huge.subdomain.with. a.long.long.long.domain.example.com", myImage: PseudoContact.makeImg("Bob", color: .red))
+        let charlie = PseudoContact(name: "Charlie", addr: "charlie@example.com", myImage: PseudoContact.makeImg("Charlie", color: .green))
         let landmarks = [
             Landmark(name: "Berlin", domain: "exampledomain.de", location: .init(latitude: 52.520008, longitude: 13.404954)),
             Landmark(name: "New York", domain: "secondexampledomain.de", location: .init(latitude: 40.730610, longitude: -73.935242)),
             Landmark(name: "Sydney", domain: "thirdexampledomain.de", location: .init(latitude: -33.865143, longitude: 151.209900))
         ]
-        let mail = PseuoMail(sender: sender, ccs: [], bccs: [], routingStops: landmarks, signedState: .ValidSignature, encState: .ValidedEncryptedWithCurrentKey)
+        let mail = PseuoMail(sender: sender,  tos: [bob,charlie], ccs: [bob, charlie,bob, charlie,bob], bccs: [], routingStops: landmarks, signedState: .ValidSignature, encState: .ValidedEncryptedWithCurrentKey)
        return ForEach(deviceNames, id: \.self) {deviceName in
-            SenderViewMain(mail: mail)
+        SenderViewMain<PseuoMail, PseudoContact>(mail: mail)
                 .previewDisplayName(deviceName)
+                .previewDevice(.init(rawValue: deviceName))
+                //.colorScheme(.dark)
         }
         
     }
 }
 
 struct PseudoContact: DisplayContact {
+    var previousMails: Int = 10
+    
+    var previousResponses: Int = 2
+        
     var name: String
     
     var addr: String
@@ -256,7 +205,7 @@ struct PseudoContact: DisplayContact {
     
     var similarContacts: [String] = []
     
-    public static func makeImageFromName(_ name: String, color: UIColor) -> Image {
+    public static func makeImg(_ name: String, color: UIColor) -> Image {
         var text: NSAttributedString
         var tag = String()
         if name.count > 0 {
@@ -301,20 +250,26 @@ struct PseudoContact: DisplayContact {
 
     }
 
-    
+    var keyRecord: KeyRecord? {
+        return nil
+    }
     
 }
 
 struct PseuoMail: DisplayMail {
+    typealias U = PseudoContact
+    
     var subject: String? = "Hello World"
     
     var body: String? = "This is my message."
     
-    var sender: DisplayContact
+    var sender: U
     
-    var ccs: [DisplayContact]
+    var tos: [U]
     
-    var bccs: [DisplayContact]
+    var ccs: [U]
+    
+    var bccs: [U]
     
     var routingStops: [Landmark]
     
@@ -322,5 +277,8 @@ struct PseuoMail: DisplayMail {
     
     var encState: EncryptionState
     
+    var persistentMail: PersistentMail? {
+        return nil
+    }
     
 }
diff --git a/enzevalos_iphone/SwiftUI/Read/Tabbed Views/SenderViewChildren/SmallContactListView.swift b/enzevalos_iphone/SwiftUI/Read/Tabbed Views/SenderViewChildren/SmallContactListView.swift
new file mode 100644
index 00000000..945e505f
--- /dev/null
+++ b/enzevalos_iphone/SwiftUI/Read/Tabbed Views/SenderViewChildren/SmallContactListView.swift	
@@ -0,0 +1,80 @@
+//
+//  SmallContactListView.swift
+//  enzevalos_iphone
+//
+//  Created by Oliver Wiese on 06.04.20.
+//  Copyright © 2020 fu-berlin. All rights reserved.
+//
+
+import SwiftUI
+
+struct SmallContactListView <C: DisplayContact>: View {
+    let contacts: [C]
+    var title: String
+    @State var showList = true
+
+    
+    var body: some View {
+         VStack (alignment: .leading, spacing: 10){
+            HStack {
+                Text(title)
+                    .font(.headline)
+                Button (action: {
+                      self.showList.toggle()
+                  }) {
+                      
+                      Image(systemName: showList ? "chevron.up" : "chevron.down")
+                          .resizable()
+                          .frame(width: 12.0, height: 7.0)
+                  }
+                Spacer()
+            }
+            if showList {
+                ForEach(contacts, id: \.addr) {contact in
+                    Group {
+                          HStack {
+                              CircleImage(image: contact.myImage, radius: 40)
+                              VStack (alignment: .leading, spacing: 2){
+                                  Text(contact.name)
+                                      .font(.subheadline)
+                                  Text(contact.addr)
+                                      .foregroundColor(.gray)
+                              }
+                              Spacer()
+                            Button(action: {self.goToContact(contact: contact)}){
+                                Image(systemName: "chevron.right")
+                            }
+                          }
+                      }
+                    .onTapGesture {
+                        self.goToContact(contact: contact)
+                    }
+                }
+                
+            }
+        }
+        .padding(10)
+    }
+    
+    private func goToContact(contact: DisplayContact) {
+        guard let con = contact.keyRecord else {
+            return
+        }
+        AppDelegate.getAppDelegate().readViewCoordinator?.pushContactView(contact: con)
+    }
+}
+
+
+struct SmallContactListView_Previews: PreviewProvider {
+    static let alice = PseudoContact(name: "Alice", addr: "alice@example.com", myImage: PseudoContact.makeImg("Alice", color: .blue))
+    static let bob = PseudoContact(name: "Bob", addr: "Bob.lord.of.kingsbridge.and.king.of.england@huge.subdomain.with. a.long.long.long.domain.example.com", myImage: PseudoContact.makeImg("Bob", color: .red))
+    static let charlie = PseudoContact(name: "Charlie", addr: "charlie@example.com", myImage: PseudoContact.makeImg("Charlie", color: .green))
+    
+    static var previews: some View {
+        VStack{
+            SmallContactListView(contacts: [alice,bob,charlie], title: "To")
+            
+            SmallContactListView(contacts: [alice,bob,charlie], title: "To", showList: false)
+        }
+    }
+}
diff --git a/enzevalos_iphone/de.lproj/Localizable.strings b/enzevalos_iphone/de.lproj/Localizable.strings
index 05c1df13..9089dee1 100644
--- a/enzevalos_iphone/de.lproj/Localizable.strings
+++ b/enzevalos_iphone/de.lproj/Localizable.strings
@@ -162,6 +162,8 @@
 "ReadView.Attachments.No" = "Keine Anhänge vorhanden";
 "ReadView.Attachments.Headline" = "Anhänge:";
 "ReadView.Links.Future" = "a list of links contained in this mail will be visable here in a future update";
+"ReadView.Sender.Previous" = "%d empfangene Mails";
+"ReadView.Sender.Responses" = "%d gesendete Mails";
 "Transportencryption" = "Transferverschlüsselung";
 "Trash" = "Papierkorb";
 "TwoDaysAgo" = "Vorgestern";
diff --git a/enzevalos_iphone/en.lproj/Localizable.strings b/enzevalos_iphone/en.lproj/Localizable.strings
index 6719f20a..95fd261c 100644
--- a/enzevalos_iphone/en.lproj/Localizable.strings
+++ b/enzevalos_iphone/en.lproj/Localizable.strings
@@ -159,6 +159,8 @@
 "ReadView.Attachments.No" = "This mail doesn't contain any attachments";
 "ReadView.Attachments.Headline" = "Attachments:";
 "ReadView.Links.Future" = "A list of links contained in this mail will be visable here in a future update";
+"ReadView.Sender.Previous" = "%d received emails";
+"ReadView.Sender.Responses" = "%d sent emails";
 "Sender" = "Sender";
 "To" = "To";
 "to" = "to";
-- 
GitLab