Commit 2a2c74ca authored by Oliver Wiese's avatar Oliver Wiese

working on user actions after receiving a mail

parent c7ebef37
......@@ -1792,7 +1792,7 @@ Um deine sicheren E-Mails auch auf einem anderen Gerät lesen zu können, muss d
<rect key="frame" x="0.0" y="0.0" width="414" height="32"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="w9U-eC-Koh">
<rect key="frame" x="8" y="-8.3333333333333357" width="30" height="38.333333333333336"/>
<rect key="frame" x="8" y="-8.3333333333333339" width="30" height="38.333333333333336"/>
<fontDescription key="fontDescription" type="system" weight="heavy" pointSize="21"/>
<state key="normal" title="✕">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
......@@ -1802,7 +1802,7 @@ Um deine sicheren E-Mails auch auf einem anderen Gerät lesen zu können, muss d
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" insetsLayoutMarginsFromSafeArea="NO" text="Kontakt verifizieren" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="25l-XT-PFo">
<rect key="frame" x="116.33333333333333" y="-2.3333333333333357" width="181.66666666666669" height="26.333333333333336"/>
<rect key="frame" x="116.33333333333333" y="-2.3333333333333339" width="181.66666666666669" height="26.333333333333336"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleTitle2"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
......@@ -2221,9 +2221,9 @@ Um deine sicheren E-Mails auch auf einem anderen Gerät lesen zu können, muss d
</scene>
</scenes>
<inferredMetricsTieBreakers>
<segue reference="3Wb-uL-BB5"/>
<segue reference="td8-VW-Wrt"/>
<segue reference="DcR-GX-scc"/>
<segue reference="rhW-cI-4c4"/>
<segue reference="hSn-Um-hji"/>
<segue reference="btx-4o-o0r"/>
<segue reference="TgN-rB-esa"/>
<segue reference="Fv4-FT-5gV"/>
<segue reference="ecN-Wn-7S0"/>
......
......@@ -15,7 +15,12 @@ struct SecurityState <M: DisplayMail> {
let mail: M
// TODO: Handling new key attack
/* TODO: MORE DIALOGS
//else if (mail.isNewPubKey) && !(mail.deleteWhileTravel){}
// message contained new public key
}
*/
var title: String {
get {
......@@ -47,6 +52,19 @@ struct SecurityState <M: DisplayMail> {
}
}
var titleIcon: UIImage {
get {
switch evaluateSecurity() {
case (_, .EncValidSign):
return StudySettings.securityIndicator.imageOfSecureIndicator()
case (_, .UnableToDecrypt), (_, .InvalidSignature):
return StudySettings.securityIndicator.imageOfCorruptedIndicator()
case (_, .NoCrypto), (_, .PlainMissingPublicKeyToVerify), (_, .PlainButValidSignature), (_, .EncNoSignature), (_, .EncButMissingPublicKeyToVerify):
return StudySettings.securityIndicator.imageOfInsecureIndicator()
}
}
}
var dialog: DialogStruct {
get {
// TODO: Do we add new public key stuff?
......@@ -154,7 +172,29 @@ struct SecurityState <M: DisplayMail> {
var warnings: [DialogStruct] {
get {
return []
var result = [DialogStruct] ()
switch evaluateSecurity() {
case (_, .EncValidSign), (_, .NoCrypto), (_, .PlainButValidSignature), (_, .EncNoSignature):
break // No warning required
case (_, .UnableToDecrypt), (_, .InvalidSignature) , (_, .PlainMissingPublicKeyToVerify), (_, .EncButMissingPublicKeyToVerify):
result.append(dialog) // warning required
}
if mail.sender.keys.count > 0 && mail.signedState == .NoSignature {
let icon = Image(systemName: "exclamationmark.triangl.fill")
let missingSignature = DialogStruct(dialogColor: Color(ThemeManager.unencryptedMessageColor()),
title: NSLocalizedString("encryptedBeforeHeadline",
comment: "encrypted by sender before"),
body: NSLocalizedString("encryptedBeforeText", comment: "encrypted by sender before"),
img: icon, messageImage: icon,
ctaButtonTitle: NSLocalizedString("Security.Dialog.Button.Title.Confirmation", comment: ""),
ctaButtonAction: .AskSenderToConfirm,
infoButtonTitle: NSLocalizedString("Security.Dialog.Button.Title.MoreInfo", comment: ""),
moreButtons: [],
dismissButtonTitle: NSLocalizedString("Security.Dialog.Button.Title.OK", comment: ""),
dismissButtonAction: .IgnoreWarning)
result.append(missingSignature)
}
return result
}
}
......
......@@ -21,27 +21,6 @@
import UIKit
import SwiftUI
/* TODO: MORE DIALOGS
//else if (mail.isNewPubKey) && !(mail.deleteWhileTravel){}
// message contained new public key
else if mail.from.hasKey && !mail.isSecure{
Text(NSLocalizedString("encryptedBeforeHeadline", comment: "encrypted by sender before"))
.font(.system(size: 25))
.frame(maxWidth: .infinity)
.background(Color.yellow)
HStack{
Text("?")
.foregroundColor(Color.orange)
.font(.system(size: 60))
.padding([.leading, .top, .bottom])
Text(NSLocalizedString("encryptedBeforeText", comment: "encrypted by sender before"))
.padding()
}
}
*/
protocol Dialog {
var dialogColor: Color { get }
var title: String { get }
......
......@@ -21,30 +21,19 @@ struct ReadMainView <M: DisplayMail>: View {
public var mail: M
@State private var currentScreen: Int = 1 //doesnt work
@State private var isSecIndExpanded:Bool = false
@State private var isSecIndExpanded = false
var body: some View {
//TODO: put into zstack instead
VStack(spacing:0){
//SecIndicator //TODO: Why the hell does expanding it reset the whole tabview
TabView{
ForEach(Tabs, id: \.id ){ tab in
tab.content
.tabItem {
tab.image
Text(tab.description)
}
TabView{
ForEach(Tabs, id: \.id ){ tab in
tab.content
.tabItem {
tab.image
Text(tab.description)
}
}
.animation(.easeInOut(duration: 0.4))
}
// .navigationBarTitle(Text((mail.trouble ? "❌" :( mail.isSecure ? "🔒" : "👀" )) + " " + (mail.subject ?? ""))
// , displayMode: .inline) //TODO: make smooth or find better solution
.navigationBarItems(trailing: moreInfoButton)
//.onAppear(perform: self.coord.setup)
//.onDisappear(perform: self.coord.reset)
}
//TODO: not use AnyView-workaround
......@@ -71,53 +60,27 @@ struct ReadMainView <M: DisplayMail>: View {
}
var moreInfoButton: some View{
return Button(action: {self.isSecIndExpanded.toggle()}){
/* NavigationLink(destination: DialogView(option: SecurityState(mail: mail).dialog, ctaAction: nil, additionalAction: nil, dismissAction: nil), label: {
Image(systemName: isSecIndExpanded ? "arrow.up.circle" : "info.circle")
}
}
/*
//securityIndicator
var SecIndicator:some View{
get{
if mail.trouble{
return AnyView(SecInd(secNum:1,isExpanded: $isSecIndExpanded, color:Color(ThemeManager.troubleMessageColor())))
}else if mail.isSecure{
return AnyView(VStack{
SecInd(secNum:2,isExpanded: $isSecIndExpanded,color:Color(ThemeManager.encryptedMessageColor()))
//TODO: Design and test
Button(action: {
self.coord.pushExportKeyView()
//let duration = Date().timeIntervalSince(opening)
//Logger.log(close: icon, mail: m, action: .exportKey, duration: duration)
//self.performSegue(withIdentifier: "exportKeyFromReadView", sender: nil)
}){
Text(NSLocalizedString("ReadMailOnOtherDevice", comment: "email is not readable on other devices"))
}
})
}
//special subcases of unsecure mail
else if mail.isCorrectlySigned {
return AnyView(SecInd(secNum:4,isExpanded: $isSecIndExpanded,color:Color(ThemeManager.unencryptedMessageColor())))
} else if mail.isEncrypted && !mail.unableToDecrypt {
return AnyView(SecInd(secNum:5,isExpanded: $isSecIndExpanded,color:Color(ThemeManager.unencryptedMessageColor())))
} else if mail.isEncrypted && mail.unableToDecrypt {
return AnyView(SecInd(secNum:6,isExpanded: $isSecIndExpanded,color:Color(ThemeManager.unencryptedMessageColor())))
}
})
.isDetailLink(false)*/
Button(action: {
self.isSecIndExpanded.toggle()
else{
return AnyView(SecInd(secNum:3,isExpanded: $isSecIndExpanded,color:Color(ThemeManager.unencryptedMessageColor())))
}
}){
Image(systemName: isSecIndExpanded ? "arrow.up.circle" : "info.circle")
}
}
*/
var naviTitle: String {
return mail.subject ?? ""
}
var detailInfo: some View {
let dialog = SecurityState(mail: mail).dialog
return DialogView(option: dialog, ctaAction: {
self.isSecIndExpanded = false
}, additionalAction: nil, dismissAction: nil)
}
}
......
......@@ -43,9 +43,12 @@ class ReadViewCoordinator {
try? AppDelegate.getAppDelegate().mailHandler.startIMAPIdleIfSupported()
AppDelegate.getAppDelegate().mailHandler.updateFolder(folder: Folder.inbox, completionCallback: {_ in
})
let secState = SecurityState.init(mail: mail)
let icon = secState.titleIcon
let view = UIImageView(image: icon)
let vc = UIHostingController(rootView: ReadMainView(mail: mail))
readView = vc
vc.navigationItem.titleView = view
root.pushViewController(vc, animated: true)
}
......
......@@ -36,7 +36,7 @@ let bob = PseudoContact(name: "Bob", addr: "Bob.lord.of.kingsbridge.and.king.of.
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(folderType: .Inbox, sender: alice, tos: [bob,charlie], ccs: [bob, charlie,bob, charlie,bob], bccs: [], routingStops: landmarks, signedState: .ValidSignature, encState: .ValidedEncryptedWithCurrentKey)
let mail = PseuoMail(folderType: .Inbox, sender: alice, tos: [bob,charlie], ccs: [bob, charlie,bob, charlie,bob], bccs: [], routingStops: landmarks, signedState: SignatureState.NoSignature, encState: .ValidedEncryptedWithCurrentKey)
protocol DisplayAttachment {
var myName: String { get }
......@@ -65,6 +65,7 @@ protocol DisplayContact {
protocol DisplayMail {
associatedtype C: DisplayContact
associatedtype D: Dialog
var subject: String? { get }
var sender: C { get }
......@@ -83,7 +84,7 @@ protocol DisplayMail {
var signedState: SignatureState { get }
var encState: EncryptionState { get }
var warnings: [DialogOption] { get }
var warnings: [D] { get }
var persistentMail: PersistentMail? { get }
......@@ -129,7 +130,7 @@ struct PseudoContact: DisplayContact {
var otherAddresses: [String] = []
var keys: [String] = []
var keys: [String] = ["ABC"]
var hasPreviousMails: Bool = false
......@@ -189,6 +190,9 @@ struct PseudoContact: DisplayContact {
}
struct PseuoMail: DisplayMail {
typealias U = PseudoContact
typealias D = DialogStruct
var displayAttachments: [DisplayAttachment] = []
func markAsRead(isRead: Bool) {
......@@ -200,9 +204,12 @@ struct PseuoMail: DisplayMail {
var isRead: Bool = false
var warnings: [DialogOption] = [DialogOption.corrupted, DialogOption.postcard]
var warnings: [D] {
get {
return SecurityState.init(mail: self).warnings
}
}
typealias U = PseudoContact
var subject: String? = "Hello World"
......
......@@ -78,7 +78,7 @@ struct SenderViewMain <M: DisplayMail>: View {
.padding(.bottom, -110/2)
.onTapGesture {
self.goToContact(contact: self.mail.sender)
}
}
}
private var sender: some View {
......
......@@ -8,9 +8,9 @@
import SwiftUI
struct DialogView : View {
struct DialogView <D: Dialog> : View {
let option: DialogOption
let option: D
var ctaAction: (() -> Void)?
var additionalAction: (() -> Void)?
var dismissAction: (() -> Void)?
......@@ -21,67 +21,55 @@ struct DialogView : View {
var body: some View {
simpleUI
}
var alternativeUI: some View {
VStack {
Text(option.title)
.font(.largeTitle)
.frame(maxWidth: .infinity, maxHeight: 100)
.cornerRadius(20)
.background(color)
.border(Color.red, width: 2)
if option.messageImage != nil {
CircleImage(image: option.messageImage!, radius: 60)
.foregroundColor(Color(option.color))
.background(Color(.white))
.padding(10)
}
}
.padding(10)
}
var simpleUI: some View {
VStack {
Text(option.title)
.font(.largeTitle)
.font(.headline)
.lineLimit(3)
.frame(maxWidth: .infinity)
.padding(.bottom, 20)
.addBorder(Color(option.color), width: 2, cornerRadius: 30)
.padding(.vertical, 20)
.addBorder(option.dialogColor, width: 2, cornerRadius: 30)
HStack{
if option.messageImage != nil {
option.messageImage!
.resizable()
.frame(width: 60, height: 60)
.foregroundColor(Color(option.color))
.padding(.trailing, 20)
}
Text(option.message)
option.img
.resizable()
.frame(width: 60, height: 60)
.foregroundColor(option.dialogColor)
.padding(.trailing, 20)
Text(option.body)
.fontWeight(.light)
.font(.body)
.lineLimit(10)
.fixedSize(horizontal: false, vertical: true)
}
.padding(20)
if option.ctaButtonTitle != nil && ctaAction != nil {
Button(action: ctaAction!) {
Text(option.ctaButtonTitle!)
.frame(maxWidth: .infinity,maxHeight: 50)
.background(RoundedCorners(color: Color(option.color), radius: 30))
.frame(maxWidth: .infinity, minHeight: 50, maxHeight: 50)
.background(RoundedCorners(color: .white, radius: 30))
.padding(.vertical, 10)
.padding(.horizontal, 20)
}
}
if option.additionActionButtonTitle != nil && additionalAction != nil {
Button(action: additionalAction!) {
Text(option.additionActionButtonTitle!)
.frame(maxWidth: .infinity,maxHeight: 50)
.background(RoundedCorners(color: color, radius: 30))
.padding(.vertical, 10)
.padding(.horizontal, 20)
}
ForEach(0..<option.moreButtons.count) { index in
Button(action: {
if let action = self.additionalAction {
action()
}
}) {
Text(self.option.moreButtons[index].title)
.frame(maxWidth: .infinity, minHeight: 50, maxHeight: 50)
.background(RoundedCorners(color: self.color, radius: 30))
.padding(.vertical, 10)
.padding(.horizontal, 20)
}
}
if option.dismissButtonTitle != nil && dismissAction != nil {
Button(action: dismissAction!) {
Text(option.dismissButtonTitle!)
.foregroundColor(.red)
.frame(maxWidth: .infinity,maxHeight: 50)
.frame(maxWidth: .infinity, minHeight: 50, maxHeight: 50)
.background(RoundedCorners(color: color, radius: 30))
.padding(.vertical, 10)
.padding(.horizontal, 20)
......@@ -93,21 +81,22 @@ struct DialogView : View {
}
}
/*
struct DialogView_Previews: PreviewProvider {
static let options = SecurityState.init(mail: mail)
static var previews: some View {
VStack{
DialogView(option: .postcard, ctaAction: action, additionalAction: action, dismissAction: action)
DialogView(option: .corrupted, ctaAction: action)
} .padding(20)
DialogView(option: options.dialog, ctaAction: action, additionalAction: action, dismissAction: action)
//DialogView(option: DialogOption.corrupted, ctaAction: action, additionalAction: action, dismissAction: action)
// DialogView(option: DialogOption.couldNotDecrypt, ctaAction: action, additionalAction: action, dismissAction: action)
}
}
static func action() {
print("Button click!")
}
}
*/
extension View {
public func addBorder<S>(_ content: S, width: CGFloat = 1, cornerRadius: CGFloat) -> some View where S : ShapeStyle {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment