mirror of
https://github.com/tutao/tutanota.git
synced 2025-10-19 16:03:43 +00:00
Use AlertCircle icon to indicate verification failures in MailRecipientsTextField
Co-authored-by: bed <bed@tutao.de>
This commit is contained in:
parent
d1acc25aab
commit
1be2f61578
9 changed files with 90 additions and 67 deletions
|
@ -1,8 +1,8 @@
|
||||||
import m, { Children, ClassComponent, Vnode } from "mithril"
|
import m, { Children, ClassComponent, Vnode } from "mithril"
|
||||||
import { BubbleTextField } from "./base/BubbleTextField.js"
|
import { BubbleTextField, BubbleTextFieldAttrs } from "./base/BubbleTextField.js"
|
||||||
import { Recipient } from "../api/common/recipients/Recipient.js"
|
import { Recipient } from "../api/common/recipients/Recipient.js"
|
||||||
import { px, size } from "./size.js"
|
import { px, size } from "./size.js"
|
||||||
import { Icon, progressIcon } from "./base/Icon.js"
|
import { Icon, IconSize, progressIcon } from "./base/Icon.js"
|
||||||
import { lang, TranslationKey } from "../misc/LanguageViewModel.js"
|
import { lang, TranslationKey } from "../misc/LanguageViewModel.js"
|
||||||
import { stringToNameAndMailAddress } from "../misc/parsing/MailAddressParser.js"
|
import { stringToNameAndMailAddress } from "../misc/parsing/MailAddressParser.js"
|
||||||
import { DropdownChildAttrs } from "./base/Dropdown.js"
|
import { DropdownChildAttrs } from "./base/Dropdown.js"
|
||||||
|
@ -11,11 +11,11 @@ import { RecipientsSearchModel } from "../misc/RecipientsSearchModel.js"
|
||||||
import { getFirstOrThrow, lazy } from "@tutao/tutanota-utils"
|
import { getFirstOrThrow, lazy } from "@tutao/tutanota-utils"
|
||||||
import { Dialog } from "./base/Dialog.js"
|
import { Dialog } from "./base/Dialog.js"
|
||||||
import { SearchDropDown } from "./SearchDropDown.js"
|
import { SearchDropDown } from "./SearchDropDown.js"
|
||||||
import { findRecipientWithAddress } from "../api/common/utils/CommonCalendarUtils.js"
|
|
||||||
import { Icons } from "./base/icons/Icons.js"
|
import { Icons } from "./base/icons/Icons.js"
|
||||||
import { theme } from "./theme.js"
|
import { theme } from "./theme.js"
|
||||||
import { getMailAddressDisplayText } from "../mailFunctionality/SharedMailUtils.js"
|
import { getMailAddressDisplayText } from "../mailFunctionality/SharedMailUtils.js"
|
||||||
import { KeyVerificationState } from "../api/worker/facades/lazy/KeyVerificationFacade"
|
import { KeyVerificationState } from "../api/worker/facades/lazy/KeyVerificationFacade"
|
||||||
|
import { WARNING_RED } from "./builtinThemes"
|
||||||
|
|
||||||
export interface MailRecipientsTextFieldAttrs {
|
export interface MailRecipientsTextFieldAttrs {
|
||||||
label: TranslationKey
|
label: TranslationKey
|
||||||
|
@ -47,7 +47,7 @@ export class MailRecipientsTextField implements ClassComponent<MailRecipientsTex
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderTextField(attrs: MailRecipientsTextFieldAttrs): Children {
|
private renderTextField(attrs: MailRecipientsTextFieldAttrs): Children {
|
||||||
return m(BubbleTextField, {
|
const bubbleTextFieldAttrs: BubbleTextFieldAttrs<Recipient> = {
|
||||||
label: attrs.label,
|
label: attrs.label,
|
||||||
text: attrs.text,
|
text: attrs.text,
|
||||||
helpLabel: attrs.helpLabel,
|
helpLabel: attrs.helpLabel,
|
||||||
|
@ -74,23 +74,41 @@ export class MailRecipientsTextField implements ClassComponent<MailRecipientsTex
|
||||||
attrs.onTextChanged(remainingText)
|
attrs.onTextChanged(remainingText)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
items: attrs.recipients.map((recipient) => recipient.address),
|
items: attrs.recipients,
|
||||||
renderBubbleText: (address: string) => {
|
getBubbleIcon: (recipient: Recipient) => {
|
||||||
const recipient = findRecipientWithAddress(attrs.recipients, address)
|
if (recipient.verificationState === KeyVerificationState.MISMATCH) {
|
||||||
if (recipient == null) {
|
return m(Icon, {
|
||||||
return lang.makeTranslation(address, getMailAddressDisplayText(null, address, false))
|
icon: Icons.AlertCircle,
|
||||||
|
size: IconSize.Large, // we want 20px
|
||||||
|
style: {
|
||||||
|
fill: WARNING_RED,
|
||||||
|
position: "relative",
|
||||||
|
top: "4px",
|
||||||
|
right: "1px",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} else if (recipient.verificationState === KeyVerificationState.VERIFIED) {
|
||||||
|
return m(Icon, {
|
||||||
|
icon: Icons.Shield,
|
||||||
|
size: IconSize.Normal,
|
||||||
|
style: {
|
||||||
|
fill: theme.content_accent,
|
||||||
|
position: "relative",
|
||||||
|
top: "2px",
|
||||||
|
right: "1px",
|
||||||
|
},
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
const name = recipient.name
|
return null
|
||||||
let verified: string = ""
|
|
||||||
if (recipient.verificationState === KeyVerificationState.MISMATCH) {
|
|
||||||
verified = " ✘"
|
|
||||||
} else if (recipient.verificationState === KeyVerificationState.VERIFIED) {
|
|
||||||
verified = " ✔"
|
|
||||||
}
|
|
||||||
return lang.makeTranslation(address, getMailAddressDisplayText(name, address, false) + verified)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getBubbleDropdownAttrs: async (address) => (await attrs.getRecipientClickedDropdownAttrs?.(address)) ?? [],
|
renderBubbleText: (recipient: Recipient) => {
|
||||||
|
const name = recipient.name
|
||||||
|
let verified: string = ""
|
||||||
|
|
||||||
|
return lang.makeTranslation(recipient.address, getMailAddressDisplayText(name, recipient.address, false) + verified)
|
||||||
|
},
|
||||||
|
getBubbleDropdownAttrs: async (recipient) => (await attrs.getRecipientClickedDropdownAttrs?.(recipient.address)) ?? [],
|
||||||
onBackspace: () => {
|
onBackspace: () => {
|
||||||
if (attrs.text === "" && attrs.recipients.length > 0) {
|
if (attrs.text === "" && attrs.recipients.length > 0) {
|
||||||
const { address } = attrs.recipients.slice().pop()!
|
const { address } = attrs.recipients.slice().pop()!
|
||||||
|
@ -136,7 +154,9 @@ export class MailRecipientsTextField implements ClassComponent<MailRecipientsTex
|
||||||
),
|
),
|
||||||
attrs.injectionsRight,
|
attrs.injectionsRight,
|
||||||
]),
|
]),
|
||||||
})
|
}
|
||||||
|
|
||||||
|
return m(BubbleTextField, bubbleTextFieldAttrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderSuggestions(attrs: MailRecipientsTextFieldAttrs): Children {
|
private renderSuggestions(attrs: MailRecipientsTextFieldAttrs): Children {
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
import m, { Children, ClassComponent, Vnode } from "mithril"
|
import m, { Children, ClassComponent, Vnode } from "mithril"
|
||||||
import { Autocomplete, TextField, TextFieldType } from "./TextField.js"
|
import { Autocomplete, TextField, TextFieldType } from "./TextField.js"
|
||||||
import { Translation, MaybeTranslation } from "../../misc/LanguageViewModel"
|
import { MaybeTranslation, Translation } from "../../misc/LanguageViewModel"
|
||||||
import { Keys } from "../../api/common/TutanotaConstants"
|
import { Keys } from "../../api/common/TutanotaConstants"
|
||||||
import { createAsyncDropdown, DropdownChildAttrs } from "./Dropdown.js"
|
import { createAsyncDropdown, DropdownChildAttrs } from "./Dropdown.js"
|
||||||
import { lazy } from "@tutao/tutanota-utils"
|
import { lazy } from "@tutao/tutanota-utils"
|
||||||
import { BaseButton } from "./buttons/BaseButton.js"
|
import { BaseButton, BaseButtonAttrs } from "./buttons/BaseButton.js"
|
||||||
|
|
||||||
export interface BubbleTextFieldAttrs {
|
export interface BubbleTextFieldAttrs<T> {
|
||||||
label: MaybeTranslation
|
label: MaybeTranslation
|
||||||
items: Array<string>
|
items: ReadonlyArray<T>
|
||||||
renderBubbleText: (item: string) => Translation
|
renderBubbleText: (item: T) => Translation
|
||||||
getBubbleDropdownAttrs: (item: string) => Promise<DropdownChildAttrs[]>
|
getBubbleIcon: (item: T) => Children
|
||||||
|
getBubbleDropdownAttrs: (item: T) => Promise<DropdownChildAttrs[]>
|
||||||
text: string
|
text: string
|
||||||
onInput: (text: string) => void
|
onInput: (text: string) => void
|
||||||
onBackspace: () => boolean
|
onBackspace: () => boolean
|
||||||
|
@ -24,11 +25,11 @@ export interface BubbleTextFieldAttrs {
|
||||||
helpLabel?: lazy<Children> | null
|
helpLabel?: lazy<Children> | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BubbleTextField implements ClassComponent<BubbleTextFieldAttrs> {
|
export class BubbleTextField<T> implements ClassComponent<BubbleTextFieldAttrs<T>> {
|
||||||
private active: boolean = false
|
private active: boolean = false
|
||||||
private domInput: HTMLInputElement | null = null
|
private domInput: HTMLInputElement | null = null
|
||||||
|
|
||||||
view({ attrs }: Vnode<BubbleTextFieldAttrs>) {
|
view({ attrs }: Vnode<BubbleTextFieldAttrs<T>>) {
|
||||||
return m(".bubble-text-field", [
|
return m(".bubble-text-field", [
|
||||||
m(TextField, {
|
m(TextField, {
|
||||||
label: attrs.label,
|
label: attrs.label,
|
||||||
|
@ -43,25 +44,29 @@ export class BubbleTextField implements ClassComponent<BubbleTextFieldAttrs> {
|
||||||
// We need overflow: hidden on both so that ellipsis on button works.
|
// We need overflow: hidden on both so that ellipsis on button works.
|
||||||
// flex is for reserving space for the comma. align-items: end so that comma is pushed to the bottom.
|
// flex is for reserving space for the comma. align-items: end so that comma is pushed to the bottom.
|
||||||
const bubbleText = attrs.renderBubbleText(item)
|
const bubbleText = attrs.renderBubbleText(item)
|
||||||
|
const bubbleIcon = attrs.getBubbleIcon(item)
|
||||||
|
|
||||||
|
const baseButtonAttrs: BaseButtonAttrs = {
|
||||||
|
label: bubbleText,
|
||||||
|
text: bubbleText.text,
|
||||||
|
class: "text-bubble button-content content-fg text-ellipsis flash",
|
||||||
|
style: {
|
||||||
|
"max-width": "100%",
|
||||||
|
},
|
||||||
|
onclick: (e: MouseEvent) => {
|
||||||
|
e.stopPropagation() // do not focus the text field
|
||||||
|
createAsyncDropdown({
|
||||||
|
lazyButtons: () => attrs.getBubbleDropdownAttrs(item),
|
||||||
|
width: 250,
|
||||||
|
})(e, e.target as HTMLElement)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if (bubbleIcon) {
|
||||||
|
baseButtonAttrs.icon = bubbleIcon
|
||||||
|
}
|
||||||
|
|
||||||
return m(".flex.overflow-hidden.items-end", [
|
return m(".flex.overflow-hidden.items-end", [
|
||||||
m(
|
m(".flex-no-grow-shrink-auto.overflow-hidden", m(BaseButton, baseButtonAttrs)),
|
||||||
".flex-no-grow-shrink-auto.overflow-hidden",
|
|
||||||
m(BaseButton, {
|
|
||||||
label: bubbleText,
|
|
||||||
text: bubbleText.text,
|
|
||||||
class: "text-bubble button-content content-fg text-ellipsis flash",
|
|
||||||
style: {
|
|
||||||
"max-width": "100%",
|
|
||||||
},
|
|
||||||
onclick: (e: MouseEvent) => {
|
|
||||||
e.stopPropagation() // do not focus the text field
|
|
||||||
createAsyncDropdown({
|
|
||||||
lazyButtons: () => attrs.getBubbleDropdownAttrs(item),
|
|
||||||
width: 250,
|
|
||||||
})(e, e.target as HTMLElement)
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
// Comma is shown when there's text/another bubble afterwards or if the field is active
|
// Comma is shown when there's text/another bubble afterwards or if the field is active
|
||||||
this.active || idx < items.length - 1 || attrs.text !== "" ? m("span.pr", ",") : null,
|
this.active || idx < items.length - 1 || attrs.text !== "" ? m("span.pr", ",") : null,
|
||||||
])
|
])
|
||||||
|
|
|
@ -10,8 +10,7 @@ import type { lazy } from "@tutao/tutanota-utils"
|
||||||
import { isNotNull } from "@tutao/tutanota-utils"
|
import { isNotNull } from "@tutao/tutanota-utils"
|
||||||
import { Icons } from "./icons/Icons.js"
|
import { Icons } from "./icons/Icons.js"
|
||||||
import { px, size } from "../size.js"
|
import { px, size } from "../size.js"
|
||||||
|
import { WARNING_RED } from "../builtinThemes"
|
||||||
const WARNING_RED = "#ca0606"
|
|
||||||
|
|
||||||
export const enum BannerType {
|
export const enum BannerType {
|
||||||
Info = "info",
|
Info = "info",
|
||||||
|
|
|
@ -108,6 +108,7 @@ export const enum Icons {
|
||||||
SpeechBubbleFill = "SpeechBubbleFill",
|
SpeechBubbleFill = "SpeechBubbleFill",
|
||||||
KeyboardFill = "KeyboardFill",
|
KeyboardFill = "KeyboardFill",
|
||||||
Shield = "Shield",
|
Shield = "Shield",
|
||||||
|
AlertCircle = "AlertCircle",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const IconsSvg: Record<Icons, string> = Object.freeze({
|
export const IconsSvg: Record<Icons, string> = Object.freeze({
|
||||||
|
@ -220,6 +221,7 @@ export const IconsSvg: Record<Icons, string> = Object.freeze({
|
||||||
SpeechBubbleFill: `<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 26 26"><path d="M23.34 10.932a10.28 10.28 0 0 0-3.62-5.844 10.66 10.66 0 0 0-6.665-2.336c-2.855 0-5.522 1.1-7.516 3.098-1.927 1.933-2.984 4.485-2.975 7.185 0 1.979.581 3.915 1.671 5.567l.204.283-1.125 4.867 5.381-1.339s.108.036.188.067c.08.03.765.293 1.493.496.604.17 1.862.422 2.848.422 2.796 0 5.407-1.082 7.352-3.05a10.33 10.33 0 0 0 2.988-7.308c0-.708-.075-1.415-.224-2.108m-14.776 3.82a1.5 1.5 0 1 1 0-2.999 1.5 1.5 0 0 1 0 2.999m4.5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3m4.5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3"/></svg>`,
|
SpeechBubbleFill: `<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 26 26"><path d="M23.34 10.932a10.28 10.28 0 0 0-3.62-5.844 10.66 10.66 0 0 0-6.665-2.336c-2.855 0-5.522 1.1-7.516 3.098-1.927 1.933-2.984 4.485-2.975 7.185 0 1.979.581 3.915 1.671 5.567l.204.283-1.125 4.867 5.381-1.339s.108.036.188.067c.08.03.765.293 1.493.496.604.17 1.862.422 2.848.422 2.796 0 5.407-1.082 7.352-3.05a10.33 10.33 0 0 0 2.988-7.308c0-.708-.075-1.415-.224-2.108m-14.776 3.82a1.5 1.5 0 1 1 0-2.999 1.5 1.5 0 0 1 0 2.999m4.5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3m4.5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3"/></svg>`,
|
||||||
KeyboardFill: `<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 26 26"><path fill-rule="evenodd" d="M23.564 20.255v-15a3 3 0 0 0-3-3h-15a3 3 0 0 0-3 3v15a3 3 0 0 0 3 3h15a3 3 0 0 0 3-3m-8-4v3h-5v-3h-4l6.5-6 6.5 6zm-9-8h13v-2h-13z" clip-rule="evenodd"/></svg>`,
|
KeyboardFill: `<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 26 26"><path fill-rule="evenodd" d="M23.564 20.255v-15a3 3 0 0 0-3-3h-15a3 3 0 0 0-3 3v15a3 3 0 0 0 3 3h15a3 3 0 0 0 3-3m-8-4v3h-5v-3h-4l6.5-6 6.5 6zm-9-8h13v-2h-13z" clip-rule="evenodd"/></svg>`,
|
||||||
Shield: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="22" viewBox="0 0 20 22"><path d="m19.959 4.55-.035-.56-.552-.098c-3.862-.693-5.474-1.194-9.078-2.822L10 .937l-.294.133C6.102 2.698 4.49 3.2.628 3.892l-.552.099-.035.559c-.172 2.728.195 5.27 1.09 7.556a15.6 15.6 0 0 0 3.2 5.023c2.386 2.532 4.92 3.632 5.404 3.827l.268.108.268-.108c.483-.195 3.018-1.295 5.405-3.827a15.6 15.6 0 0 0 3.192-5.023c.896-2.286 1.263-4.828 1.09-7.556M8.668 14.193l-3.25-3.186 1-1.02 2.164 2.12L13.5 6.428l1.08.935z"/></svg>`,
|
Shield: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="22" viewBox="0 0 20 22"><path d="m19.959 4.55-.035-.56-.552-.098c-3.862-.693-5.474-1.194-9.078-2.822L10 .937l-.294.133C6.102 2.698 4.49 3.2.628 3.892l-.552.099-.035.559c-.172 2.728.195 5.27 1.09 7.556a15.6 15.6 0 0 0 3.2 5.023c2.386 2.532 4.92 3.632 5.404 3.827l.268.108.268-.108c.483-.195 3.018-1.295 5.405-3.827a15.6 15.6 0 0 0 3.192-5.023c.896-2.286 1.263-4.828 1.09-7.556M8.668 14.193l-3.25-3.186 1-1.02 2.164 2.12L13.5 6.428l1.08.935z"/></svg>`,
|
||||||
|
AlertCircle: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 2.25c-5.376 0-9.75 4.374-9.75 9.75s4.374 9.75 9.75 9.75 9.75-4.374 9.75-9.75S17.376 2.25 12 2.25m.938 14.996h-1.876V15.37h1.876zm-.188-2.996h-1.5l-.281-7.5h2.062z"/></svg>`,
|
||||||
} as const)
|
} as const)
|
||||||
|
|
||||||
export const SecondFactorImage =
|
export const SecondFactorImage =
|
||||||
|
|
|
@ -8,6 +8,8 @@ import { client } from "../misc/ClientDetector.js"
|
||||||
|
|
||||||
assertMainOrNodeBoot()
|
assertMainOrNodeBoot()
|
||||||
|
|
||||||
|
export const WARNING_RED = "#ca0606"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* light theme background
|
* light theme background
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -49,7 +49,7 @@ export class KeyManagementSettingsViewer implements UpdatableSettingsViewer {
|
||||||
}
|
}
|
||||||
|
|
||||||
async entityEventsReceived(updates: ReadonlyArray<EntityUpdateData>): Promise<void> {
|
async entityEventsReceived(updates: ReadonlyArray<EntityUpdateData>): Promise<void> {
|
||||||
m.redraw()
|
// noop operation because key trusted entities are not stored only locally and will not trigger an entity event.
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ export class KeyManagementSettingsViewer implements UpdatableSettingsViewer {
|
||||||
const obj: KeyManagementSettingsViewer = this
|
const obj: KeyManagementSettingsViewer = this
|
||||||
|
|
||||||
const selfMailAddress = assertNotNull(this.mailAddress)
|
const selfMailAddress = assertNotNull(this.mailAddress)
|
||||||
const selfFingerprint = assertNotNull(this.publicKeyHash)
|
const selfFingerprint = this.publicKeyHash
|
||||||
|
|
||||||
const addressRows = Array.from(this.trustedIdentities.entries()).map(([mailAddress, publicKeyFingerprint]: [string, PublicKeyFingerprint]) => {
|
const addressRows = Array.from(this.trustedIdentities.entries()).map(([mailAddress, publicKeyFingerprint]: [string, PublicKeyFingerprint]) => {
|
||||||
return m(FingerprintRow, {
|
return m(FingerprintRow, {
|
||||||
|
@ -100,7 +100,7 @@ export class KeyManagementSettingsViewer implements UpdatableSettingsViewer {
|
||||||
title: lang.get("keyManagement.keyVerification_label"),
|
title: lang.get("keyManagement.keyVerification_label"),
|
||||||
subTitle: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr.",
|
subTitle: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr.",
|
||||||
}),
|
}),
|
||||||
this.renderQrTextMethod(selfMailAddress, selfFingerprint),
|
selfFingerprint ? this.renderQrTextMethod(selfMailAddress, selfFingerprint) : null,
|
||||||
m(".small.text-break.text-center.mb-l", lang.get("keyManagement.publicKeyFingerprintQrInfo_msg")),
|
m(".small.text-break.text-center.mb-l", lang.get("keyManagement.publicKeyFingerprintQrInfo_msg")),
|
||||||
|
|
||||||
m(MenuTitle, { content: lang.get("keyManagement.verificationPool_label") }),
|
m(MenuTitle, { content: lang.get("keyManagement.verificationPool_label") }),
|
||||||
|
|
|
@ -40,17 +40,6 @@ export async function showKeyVerificationWizard(
|
||||||
const usageTest = usageTestController.getTest("crypto.keyVerification")
|
const usageTest = usageTestController.getTest("crypto.keyVerification")
|
||||||
// const stage = usageTest.getStage(0)
|
// const stage = usageTest.getStage(0)
|
||||||
// await completeStageNow(stage)
|
// await completeStageNow(stage)
|
||||||
//
|
|
||||||
const data: KeyVerificationWizardData = {
|
|
||||||
keyVerificationFacade: keyVerificationFacade,
|
|
||||||
mobileSystemFacade: mobileSystemFacade,
|
|
||||||
method: KeyVerificationMethodType.text, // will be overwritten by the wizard
|
|
||||||
reloadParent: reloadParent, // will be called after a key has been pinned
|
|
||||||
mailAddress: "",
|
|
||||||
publicKeyFingerprint: null,
|
|
||||||
result: null,
|
|
||||||
usageTest: usageTest,
|
|
||||||
}
|
|
||||||
|
|
||||||
const model = new KeyVerificationModel(keyVerificationFacade, mobileSystemFacade)
|
const model = new KeyVerificationModel(keyVerificationFacade, mobileSystemFacade)
|
||||||
const multiPageDialog: Dialog = new MultiPageDialog<KeyVerificationWizardPages>(KeyVerificationWizardPages.CHOOSE_METHOD)
|
const multiPageDialog: Dialog = new MultiPageDialog<KeyVerificationWizardPages>(KeyVerificationWizardPages.CHOOSE_METHOD)
|
||||||
|
@ -67,12 +56,18 @@ export async function showKeyVerificationWizard(
|
||||||
case KeyVerificationWizardPages.BY_TEXT_INPUT_METHOD: // TODO: rename to EMAIL INPUT METHOD?
|
case KeyVerificationWizardPages.BY_TEXT_INPUT_METHOD: // TODO: rename to EMAIL INPUT METHOD?
|
||||||
return m(VerificationByTextPage, {
|
return m(VerificationByTextPage, {
|
||||||
model,
|
model,
|
||||||
goToSuccessPage: () => navigateToPage(KeyVerificationWizardPages.SUCCESS),
|
goToSuccessPage: () => {
|
||||||
|
reloadParent()
|
||||||
|
navigateToPage(KeyVerificationWizardPages.SUCCESS)
|
||||||
|
},
|
||||||
})
|
})
|
||||||
case KeyVerificationWizardPages.BY_QR_CODE_INPUT_METHOD:
|
case KeyVerificationWizardPages.BY_QR_CODE_INPUT_METHOD:
|
||||||
return m(VerificationByQrCodePage, {
|
return m(VerificationByQrCodePage, {
|
||||||
model,
|
model,
|
||||||
goToSuccessPage: () => navigateToPage(KeyVerificationWizardPages.SUCCESS),
|
goToSuccessPage: () => {
|
||||||
|
reloadParent()
|
||||||
|
navigateToPage(KeyVerificationWizardPages.SUCCESS)
|
||||||
|
},
|
||||||
})
|
})
|
||||||
case KeyVerificationWizardPages.SUCCESS:
|
case KeyVerificationWizardPages.SUCCESS:
|
||||||
return m(VerificationResultPage, {
|
return m(VerificationResultPage, {
|
||||||
|
|
|
@ -60,8 +60,8 @@ export class VerificationByQrCodePage implements Component<VerificationByQrCodeP
|
||||||
".align-self-center.full-width",
|
".align-self-center.full-width",
|
||||||
m(LoginButton, {
|
m(LoginButton, {
|
||||||
label: markAsVerifiedTranslationKey,
|
label: markAsVerifiedTranslationKey,
|
||||||
onclick: () => {
|
onclick: async () => {
|
||||||
model.trust()
|
await model.trust()
|
||||||
goToSuccessPage()
|
goToSuccessPage()
|
||||||
},
|
},
|
||||||
disabled: model.result !== KeyVerificationResultType.QR_OK,
|
disabled: model.result !== KeyVerificationResultType.QR_OK,
|
||||||
|
|
|
@ -81,8 +81,8 @@ export class VerificationByTextPage implements Component<VerificationByTextPageA
|
||||||
".align-self-center.full-width",
|
".align-self-center.full-width",
|
||||||
m(LoginButton, {
|
m(LoginButton, {
|
||||||
label: markAsVerifiedTranslationKey,
|
label: markAsVerifiedTranslationKey,
|
||||||
onclick: () => {
|
onclick: async () => {
|
||||||
model.trust()
|
await model.trust()
|
||||||
goToSuccessPage()
|
goToSuccessPage()
|
||||||
}, // TODO also go to results page
|
}, // TODO also go to results page
|
||||||
disabled: isFingerprintMissing(model),
|
disabled: isFingerprintMissing(model),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue