seekia/gui/toolsGui.go

738 lines
27 KiB
Go
Raw Normal View History

package gui
// toolsGui.go implements pages to use Seekia tools
// Tools are various utilities to perform tasks such as generating identity hashes, verifying memos, and more
import "fyne.io/fyne/v2"
import "fyne.io/fyne/v2/container"
import "fyne.io/fyne/v2/data/binding"
import "fyne.io/fyne/v2/dialog"
import "fyne.io/fyne/v2/layout"
import "fyne.io/fyne/v2/theme"
import "fyne.io/fyne/v2/widget"
import "seekia/internal/cryptocurrency/cardanoAddress"
import "seekia/internal/cryptocurrency/ethereumAddress"
import "seekia/internal/encoding"
import "seekia/internal/helpers"
import "seekia/internal/identity"
import "seekia/internal/memos/createMemos"
import "seekia/internal/memos/readMemos"
import "seekia/internal/myIdentity"
import "seekia/internal/mySettings"
import "seekia/internal/seedPhrase"
import "errors"
func setToolsPage(window fyne.Window, previousPage func()){
currentPage := func(){setToolsPage(window, previousPage)}
title := getPageTitleCentered("Tools")
backButton := getBackButtonCentered(previousPage)
moderateButton := widget.NewButton("Moderate", func(){
setModeratePage(window, true, currentPage)
})
hostButton := widget.NewButton(translate("Host"), func(){
setHostPage(window, true, currentPage)
})
networkStatisticsButton := widget.NewButton(translate("Network Statistics"), func(){
setNetworkStatisticsPage(window, currentPage)
})
generateCustomIdentityHashButton := widget.NewButton("Generate Custom Identity Hash", func(){
setChooseIdentityTypeForNewIdentityHashPage(window, currentPage)
})
deriveIdentityScoreAddressButton := widget.NewButton("Derive Identity Score Addresses", func(){
setDeriveIdentityScoreAddressesPage(window, currentPage)
})
createMemoButton := widget.NewButton("Create Memo", func(){
setCreateMemoPage(window, false, "", currentPage)
})
verifyMemoButton := widget.NewButton("Verify Memo", func(){
setVerifyMemoPage(window, currentPage)
})
buttonsGrid := container.NewGridWithColumns(1, moderateButton, hostButton, networkStatisticsButton, generateCustomIdentityHashButton, deriveIdentityScoreAddressButton, createMemoButton, verifyMemoButton)
buttonsGridCentered := getContainerCentered(buttonsGrid)
page := container.NewVBox(title, backButton, widget.NewSeparator(), buttonsGridCentered)
setPageContent(page, window)
}
// This page is used to generate a new identity hash from the tools menu, not for the user's own identity
// The identity hash that is generated will not be saved to the disk when the user exits the utility.
func setChooseIdentityTypeForNewIdentityHashPage(window fyne.Window, previousPage func()){
currentPage := func(){setChooseIdentityTypeForNewIdentityHashPage(window, previousPage)}
title := getPageTitleCentered("Create New Identity Hash")
backButton := getBackButtonCentered(previousPage)
description1 := getLabelCentered("Choose the identity type for your new identity hash.")
description2 := getLabelCentered("The last character of the identity hash will be different for each identity type.")
description3 := getLabelCentered("Mate = m, Host = h, Moderator = r")
description4 := getLabelCentered("You can change this later by importing the seed phrase as a different identity type.")
getChooseIdentityTypeButtonWithIcon := func(identityType string)(*fyne.Container, error){
identityTypeIcon, err := getIdentityTypeIcon(identityType, -2)
if (err != nil) { return nil, err }
submitPage := func(seedPhrase string, previousPageFunction func()){
setViewNewSeedPhrasePage(window, identityType, seedPhrase, previousPageFunction, currentPage)
}
chooseIdentityTypeButton := widget.NewButton(identityType, func(){
setCreateCustomIdentityHashPage(window, identityType, false, 0, 0, currentPage, submitPage)
})
buttonWithIcon := container.NewGridWithColumns(1, identityTypeIcon, chooseIdentityTypeButton)
return buttonWithIcon, nil
}
mateButtonWithIcon, err := getChooseIdentityTypeButtonWithIcon("Mate")
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
hostButtonWithIcon, err := getChooseIdentityTypeButtonWithIcon("Host")
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
moderatorButtonWithIcon, err := getChooseIdentityTypeButtonWithIcon("Moderator")
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
chooseIdentityTypeButtonsRow := getContainerCentered(container.NewGridWithRows(1, mateButtonWithIcon, hostButtonWithIcon, moderatorButtonWithIcon))
page := container.NewVBox(title, backButton, widget.NewSeparator(), description1, description2, description3, description4, widget.NewSeparator(), chooseIdentityTypeButtonsRow)
setPageContent(page, window)
}
// This page is used to view a newly generated seed phrase from the generation tool.
// The seed phrase is not saved anywhere
func setViewNewSeedPhrasePage(window fyne.Window, identityType string, newSeedPhrase string, previousPage func(), nextPage func()){
title := getPageTitleCentered("View New Identity Hash")
backButton := getBackButtonCentered(previousPage)
description1 := getLabelCentered("Here is your generated identity hash.")
newSeedPhraseHash, err := seedPhrase.ConvertSeedPhraseToSeedPhraseHash(newSeedPhrase)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
newIdentityHash, err := identity.GetIdentityHashFromSeedPhraseHash(newSeedPhraseHash, identityType)
if (err != nil) {
setErrorEncounteredPage(window, err, previousPage)
return
}
newIdentityHashString, _, err := identity.EncodeIdentityHashBytesToString(newIdentityHash)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
identityHashBox := getContainerCentered(getWidgetBoxed(getBoldLabel(newIdentityHashString)))
doneButton := getWidgetCentered(widget.NewButtonWithIcon("Done", theme.ConfirmIcon(), nextPage))
description2 := getBoldLabelCentered("When you press Done, this identity hash will be deleted.")
description3 := getLabelCentered("Write down this seed phrase to save this identity.")
seedPhraseLabel := widget.NewMultiLineEntry()
seedPhraseLabel.Wrapping = 3
seedPhraseLabel.SetText(newSeedPhrase)
seedPhraseLabel.OnChanged = func(_ string){
seedPhraseLabel.SetText(newSeedPhrase)
}
seedPhraseLabelBoxed := getWidgetBoxed(seedPhraseLabel)
widener := widget.NewLabel(" ")
seedPhraseLabelWidened := getContainerCentered(container.NewGridWithColumns(1, seedPhraseLabelBoxed, widener))
page := container.NewVBox(title, backButton, widget.NewSeparator(), description1, identityHashBox, doneButton, widget.NewSeparator(), description2, description3, seedPhraseLabelWidened)
setPageContent(page, window)
}
func setDeriveIdentityScoreAddressesPage(window fyne.Window, previousPage func()){
title := getPageTitleCentered("Derive Identity Score Addresses")
backButton := getBackButtonCentered(previousPage)
description1 := getLabelCentered("Convert a moderator's identity hash to their identity score cryptocurrency addresses.")
description2 := getLabelCentered("Send cryptocurrency to these addresses to increase the user's identity score.")
enterIdentityHashLabel := getBoldLabelCentered(" Enter Identity Hash: ")
identityHashEntry := widget.NewEntry()
identityHashEntry.SetPlaceHolder("Enter Identity Hash.")
identityHashEntryBoxed := getWidgetBoxed(identityHashEntry)
enterIdentityHashLabelWithEntry := getContainerCentered(container.NewGridWithColumns(1, enterIdentityHashLabel, identityHashEntryBoxed))
ethereumLabel := getBoldLabelCentered(" Ethereum: ")
cardanoLabel := getBoldLabelCentered("Cardano:")
addressBinding_Ethereum := binding.NewString()
addressBinding_Cardano := binding.NewString()
addressEntry_Ethereum := widget.NewEntry()
addressEntry_Cardano := widget.NewEntry()
addressEntryOnChangedFunction_Ethereum := func(_ string){
currentAddress, err := addressBinding_Ethereum.Get()
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
addressEntry_Ethereum.SetText(currentAddress)
}
addressEntryOnChangedFunction_Cardano := func(_ string){
currentAddress, err := addressBinding_Cardano.Get()
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
addressEntry_Cardano.SetText(currentAddress)
}
addressEntry_Ethereum.OnChanged = addressEntryOnChangedFunction_Ethereum
addressEntry_Ethereum.SetPlaceHolder("The Ethereum identity score address will display here.")
addressEntryBoxed_Ethereum := getWidgetBoxed(addressEntry_Ethereum)
addressEntry_Cardano.OnChanged = addressEntryOnChangedFunction_Cardano
addressEntry_Cardano.SetPlaceHolder("The Cardano identity score address will display here.")
addressEntryBoxed_Cardano := getWidgetBoxed(addressEntry_Cardano)
deriveButton := getWidgetCentered(widget.NewButtonWithIcon("Derive", theme.MoveDownIcon(), func(){
inputIdentityHashString := identityHashEntry.Text
if (inputIdentityHashString == "Admin"){
setAdminToolsPage(window)
return
}
if (inputIdentityHashString == ""){
addressBinding_Ethereum.Set("")
addressBinding_Cardano.Set("")
addressEntry_Ethereum.SetText("")
addressEntry_Cardano.SetText("")
dialogTitle := translate("No Identity Hash Provided")
dialogMessage := getLabelCentered("You must enter an identity hash.")
dialogContent := container.NewVBox(dialogMessage)
dialog.ShowCustom(dialogTitle, translate("Close"), dialogContent, window)
return
}
inputIdentityHash, identityType, err := identity.ReadIdentityHashString(inputIdentityHashString)
if (err != nil){
addressBinding_Ethereum.Set("")
addressBinding_Cardano.Set("")
addressEntry_Ethereum.SetText("")
addressEntry_Cardano.SetText("")
dialogTitle := translate("Identity Hash Is Invalid")
dialogMessage1 := getLabelCentered("The identity hash you have entered is invalid.")
dialogMessage2 := getLabelCentered("Identity hashes are 27 characters long.")
dialogContent := container.NewVBox(dialogMessage1, dialogMessage2)
dialog.ShowCustom(dialogTitle, translate("Close"), dialogContent, window)
return
}
if (identityType != "Moderator"){
addressBinding_Ethereum.Set("")
addressBinding_Cardano.Set("")
addressEntry_Ethereum.SetText("")
addressEntry_Cardano.SetText("")
dialogTitle := translate("Identity Hash Is Invalid")
dialogMessage1 := getLabelCentered("The identity hash you have entered is not a moderator identity.")
dialogMessage2 := getLabelCentered("Moderator identity hashes end with an r character.")
dialogContent := container.NewVBox(dialogMessage1, dialogMessage2)
dialog.ShowCustom(dialogTitle, translate("Close"), dialogContent, window)
return
}
identityScoreAddress_Ethereum, err := ethereumAddress.GetIdentityScoreEthereumAddressFromIdentityHash(inputIdentityHash)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
err = addressBinding_Ethereum.Set(identityScoreAddress_Ethereum)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
addressEntry_Ethereum.SetText(identityScoreAddress_Ethereum)
identityScoreAddress_Cardano, err := cardanoAddress.GetIdentityScoreCardanoAddressFromIdentityHash(inputIdentityHash)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
err = addressBinding_Cardano.Set(identityScoreAddress_Cardano)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
addressEntry_Cardano.SetText(identityScoreAddress_Cardano)
}))
resultAddressesSection := getContainerCentered(container.NewGridWithColumns(1, ethereumLabel, addressEntryBoxed_Ethereum, cardanoLabel, addressEntryBoxed_Cardano))
page := container.NewVBox(title, backButton, widget.NewSeparator(), description1, description2, widget.NewSeparator(), enterIdentityHashLabelWithEntry, deriveButton, widget.NewSeparator(), resultAddressesSection)
setPageContent(page, window)
}
func setCreateMemoPage(window fyne.Window, messageExists bool, messageText string, previousPage func()){
currentPage := func(){setCreateMemoPage(window, messageExists, messageText, previousPage)}
title := getPageTitleCentered("Create Memo")
backButton := getBackButtonCentered(previousPage)
description := widget.NewLabel("This page allows you to create a Seekia memo.")
memoHelpButton := widget.NewButtonWithIcon("", theme.QuestionIcon(), func(){
setMemoExplainerPage(window, currentPage)
})
descriptionRow := container.NewHBox(layout.NewSpacer(), description, memoHelpButton, layout.NewSpacer())
identityTypesList := []string{"Mate", "Host", "Moderator"}
myIdentityHashesList := make([]string, 0)
for _, identityType := range identityTypesList{
myIdentityExists, myIdentityHash, err := myIdentity.GetMyIdentityHash(identityType)
if (err != nil) {
setErrorEncounteredPage(window, err, previousPage)
return
}
if (myIdentityExists == false){
continue
}
myIdentityHashString, _, err := identity.EncodeIdentityHashBytesToString(myIdentityHash)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
myIdentityHashesList = append(myIdentityHashesList, myIdentityHashString)
}
if (len(myIdentityHashesList) == 0){
description2 := getBoldLabelCentered("No identities exist.")
description3 := getLabelCentered("You must create a Seekia identity to create a memo.")
description4 := getLabelCentered("Create your identity on the Settings - My Data - My Identity Hashes page.")
page := container.NewVBox(title, backButton, widget.NewSeparator(), descriptionRow, widget.NewSeparator(), description2, description3, description4)
setPageContent(page, window)
return
}
chooseIdentityLabel := getBoldLabelCentered("Choose Identity:")
chooseIdentitySelector := widget.NewSelect(myIdentityHashesList, nil)
chooseIdentitySelector.Selected = myIdentityHashesList[0]
chooseIdentitySelectorCentered := getWidgetCentered(chooseIdentitySelector)
chooseDecorationLabel := getBoldLabelCentered("Choose Decoration:")
decorationOptionsList := []string{
"«« Seekia Memo »»",
"⁕ Seekia Memo ⁕",
"⁂ Seekia Memo ⁂",
"※ Seekia Memo ※",
}
chooseDecorationSelector := widget.NewSelect(decorationOptionsList, func(newDecoration string){
err := mySettings.SetSetting("MemoDecoration", newDecoration)
if (err != nil){
setErrorEncounteredPage(window, err, currentPage)
return
}
})
getCurrentMemoDecoration := func()(string, error){
exists, memoDecoration, err := mySettings.GetSetting("MemoDecoration")
if (err != nil) { return "", err }
if (exists == false){
return "«« Seekia Memo »»", nil
}
return memoDecoration, nil
}
currentMemoDecoration, err := getCurrentMemoDecoration()
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
chooseDecorationSelector.Selected = currentMemoDecoration
chooseDecorationSelectorCentered := getWidgetCentered(chooseDecorationSelector)
chooseMessageOptionsGrid := getContainerCentered(container.NewGridWithColumns(2, chooseIdentityLabel, chooseDecorationLabel, chooseIdentitySelectorCentered, chooseDecorationSelectorCentered))
enterTextLabel := getBoldLabelCentered("Enter Message:")
header := container.NewVBox(title, backButton, widget.NewSeparator(), descriptionRow, widget.NewSeparator(), chooseMessageOptionsGrid, widget.NewSeparator(), enterTextLabel)
enterMessageEntry := widget.NewMultiLineEntry()
if (messageExists == true){
enterMessageEntry.SetText(messageText)
} else {
enterMessageEntry.SetPlaceHolder("Enter Message...")
}
createMemoButton := getWidgetCentered(widget.NewButtonWithIcon("Create Memo", theme.ConfirmIcon(), func(){
newMemoMessage := enterMessageEntry.Text
if (newMemoMessage == ""){
title := translate("No Message Provided")
dialogMessage := getLabelCentered(translate("You must enter a message to create a memo."))
dialogContent := container.NewVBox(dialogMessage)
dialog.ShowCustom(title, translate("Close"), dialogContent, window)
return
}
myIdentityHashString := chooseIdentitySelector.Selected
myIdentityHash, _, err := identity.ReadIdentityHashString(myIdentityHashString)
if (err != nil){
setErrorEncounteredPage(window, err, currentPage)
return
}
identityFound, myPublicIdentityKey, myPrivateIdentityKey, err := myIdentity.GetMyPublicPrivateIdentityKeysFromIdentityHash(myIdentityHash)
if (err != nil){
setErrorEncounteredPage(window, err, currentPage)
return
}
if (identityFound == false){
setErrorEncounteredPage(window, errors.New("My identity not found after being found already."), currentPage)
return
}
myIdentityType, err := identity.GetIdentityTypeFromIdentityHash(myIdentityHash)
if (err != nil){
setErrorEncounteredPage(window, err, currentPage)
return
}
getNewMemoDecorations := func()(string, string, error){
exists, myMemoDecoration, err := mySettings.GetSetting("MemoDecoration")
if (err != nil) { return "", "", err }
if (exists == false){
return "««", "»»", nil
}
if (myMemoDecoration == "«« Seekia Memo »»"){
return "««", "»»", nil
}
if (myMemoDecoration == "⁕ Seekia Memo ⁕"){
return "⁕", "⁕", nil
}
if (myMemoDecoration == "⁂ Seekia Memo ⁂"){
return "⁂", "⁂", nil
}
if (myMemoDecoration == "※ Seekia Memo ※"){
return "※", "※", nil
}
return "", "", errors.New("MySettings contains unknown MemoDecoration: " + myMemoDecoration)
}
newMemoDecorationPrefix, newMemoDecorationSuffix, err := getNewMemoDecorations()
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
newMemoString, err := createMemos.CreateMemo(myPublicIdentityKey, myPrivateIdentityKey, myIdentityType, newMemoDecorationPrefix, newMemoDecorationSuffix, newMemoMessage)
if (err != nil){
setErrorEncounteredPage(window, err, currentPage)
return
}
// We use this function so that the current memo is not lost if the user goes back
nextPagePreviousPage := func(){
setCreateMemoPage(window, true, newMemoMessage, previousPage)
}
setViewCreatedMemoButton(window, newMemoString, nextPagePreviousPage)
}))
emptyLabel := widget.NewLabel("")
createMemoButtonWithSpacer := container.NewVBox(createMemoButton, emptyLabel)
page := container.NewBorder(header, createMemoButtonWithSpacer, nil, nil, enterMessageEntry)
setPageContent(page, window)
}
func setViewCreatedMemoButton(window fyne.Window, memoString string, previousPage func()){
currentPage := func(){setViewCreatedMemoButton(window, memoString, previousPage)}
title := getPageTitleCentered(translate("View Memo"))
backButton := getBackButtonCentered(previousPage)
description1 := getLabelCentered("Here is your new Memo.")
description2 := getLabelCentered("Send funds to the crypto addresses to timestamp your memo.")
memoIsValid, memoHash, _, _, err := readMemos.ReadMemo(memoString)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
if (memoIsValid == false){
setErrorEncounteredPage(window, errors.New("setViewCreatedMemoButton called with invalid memo."), previousPage)
return
}
viewCryptocurrencyAddressesButton := getWidgetCentered(widget.NewButtonWithIcon("View Cryptocurrency Addresses", theme.VisibilityIcon(), func(){
setViewMemoCryptocurrencyAddressesPage(window, memoHash, "Ethereum", currentPage)
}))
memoHashTitle := widget.NewLabel("Memo Hash:")
memoHashHex := encoding.EncodeBytesToHexString(memoHash[:])
memoHashTrimmed, _, err := helpers.TrimAndFlattenString(memoHashHex, 15)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
memoHashLabel := getBoldLabel(memoHashTrimmed)
viewMemoHashButton := widget.NewButtonWithIcon("", theme.VisibilityIcon(), func(){
setViewContentHashPage(window, "Memo", memoHash[:], currentPage)
})
memoHashRow := container.NewHBox(layout.NewSpacer(), memoHashTitle, memoHashLabel, viewMemoHashButton, layout.NewSpacer())
header := container.NewVBox(title, backButton, widget.NewSeparator(), description1, description2, widget.NewSeparator(), viewCryptocurrencyAddressesButton, widget.NewSeparator(), memoHashRow, widget.NewSeparator())
memoTextBox := widget.NewEntry()
memoTextBox.SetText(memoString)
memoTextBox.OnChanged = func(_ string){
memoTextBox.SetText(memoString)
}
page := container.NewBorder(header, nil, nil, nil, memoTextBox)
setPageContent(page, window)
}
func setViewMemoCryptocurrencyAddressesPage(window fyne.Window, memoHash [32]byte, cryptocurrencyName string, previousPage func()){
if (cryptocurrencyName != "Ethereum" && cryptocurrencyName != "Cardano"){
setErrorEncounteredPage(window, errors.New("setViewMemoCryptocurrencyAddressesPage called with invalid cryptocurrencyName: " + cryptocurrencyName), previousPage)
}
currentPage := func(){setViewMemoCryptocurrencyAddressesPage(window, memoHash, cryptocurrencyName, previousPage)}
title := getPageTitleCentered("View Memo Cryptocurrency Addresses")
backButton := getBackButtonCentered(previousPage)
description1 := getLabelCentered("Below is the " + cryptocurrencyName + " address for this memo.")
description2 := getLabelCentered("Send funds to this address to timestamp the memo.")
description3 := getLabelCentered("Anyone can verify that the memo existed at the time of the earliest transaction to the address.")
cryptocurrencyIcon, err := getFyneImageIcon(cryptocurrencyName)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
switchCryptocurrencyButton := widget.NewButton(cryptocurrencyName, func(){
if (cryptocurrencyName == "Ethereum"){
setViewMemoCryptocurrencyAddressesPage(window, memoHash, "Cardano", previousPage)
} else {
setViewMemoCryptocurrencyAddressesPage(window, memoHash, "Ethereum", previousPage)
}
})
switchCryptocurrencyButtonWithIcon := getContainerCentered(container.NewGridWithColumns(1, cryptocurrencyIcon, switchCryptocurrencyButton))
cryptocurrencyAddress, err := readMemos.GetBlockchainAddressFromMemoHash(cryptocurrencyName, memoHash)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
addressWithButtonsRow, err := getCryptocurrencyAddressLabelWithCopyAndQRButtons(window, cryptocurrencyName, cryptocurrencyAddress, currentPage)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
page := container.NewVBox(title, backButton, widget.NewSeparator(), description1, description2, description3, widget.NewSeparator(), switchCryptocurrencyButtonWithIcon, widget.NewSeparator(), addressWithButtonsRow)
setPageContent(page, window)
}
func setVerifyMemoPage(window fyne.Window, previousPage func()){
currentPage := func(){setVerifyMemoPage(window, previousPage)}
title := getPageTitleCentered("Verify Memo")
backButton := getBackButtonCentered(previousPage)
description := widget.NewLabel("This page can be used to verify a Seekia memo.")
memoHelpButton := widget.NewButtonWithIcon("", theme.QuestionIcon(), func(){
setMemoExplainerPage(window, currentPage)
})
descriptionRow := container.NewHBox(layout.NewSpacer(), description, memoHelpButton, layout.NewSpacer())
memoEntry := widget.NewMultiLineEntry()
verifyButton := getWidgetCentered(widget.NewButtonWithIcon("Verify", theme.NavigateNextIcon(), func(){
memoToVerify := memoEntry.Text
if (memoToVerify == ""){
dialogTitle := translate("No Memo Provided")
dialogMessage := getLabelCentered("The must enter a memo to verify.")
dialogContent := container.NewVBox(dialogMessage)
dialog.ShowCustom(dialogTitle, translate("Close"), dialogContent, window)
return
}
memoIsValid, _, _, _, err := readMemos.ReadMemo(memoToVerify)
if (err != nil){
setErrorEncounteredPage(window, err, currentPage)
return
}
if (memoIsValid == false){
dialogTitle := translate("Memo Is Invalid")
dialogMessageA := getBoldLabelCentered("The memo you have entered is invalid.")
dialogMessageB := getLabelCentered("You cannot trust that it was written by its alleged author.")
dialogContent := container.NewVBox(dialogMessageA, dialogMessageB)
dialog.ShowCustom(dialogTitle, translate("Close"), dialogContent, window)
return
}
setViewVerifiedMemoInfoPage(window, memoToVerify, currentPage)
}))
emptyLabel := widget.NewLabel("")
verifyButtonWithSpacer := container.NewVBox(verifyButton, emptyLabel)
header := container.NewVBox(title, backButton, widget.NewSeparator(), descriptionRow)
page := container.NewBorder(header, verifyButtonWithSpacer, nil, nil, memoEntry)
setPageContent(page, window)
}
func setViewVerifiedMemoInfoPage(window fyne.Window, memoString string, previousPage func()){
currentPage := func(){setViewVerifiedMemoInfoPage(window, memoString, previousPage)}
title := getPageTitleCentered("View Memo Info")
backButton := getBackButtonCentered(previousPage)
description := getBoldLabelCentered("The memo is valid!")
memoIsValid, memoHash, authorIdentityHash, memoUnarmoredContents, err := readMemos.ReadMemo(memoString)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
if (memoIsValid == false){
setErrorEncounteredPage(window, errors.New("setViewVerifiedMemoInfoPage called with invalid memo: " + memoString), previousPage)
return
}
memoHashTitle := widget.NewLabel("Memo Hash:")
memoHashHex := encoding.EncodeBytesToHexString(memoHash[:])
memoHashTrimmed, _, err := helpers.TrimAndFlattenString(memoHashHex, 15)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
memoHashLabel := getBoldLabel(memoHashTrimmed)
viewMemoHashButton := widget.NewButtonWithIcon("", theme.VisibilityIcon(), func(){
setViewContentHashPage(window, "Memo", memoHash[:], currentPage)
})
memoHashRow := container.NewHBox(layout.NewSpacer(), memoHashTitle, memoHashLabel, viewMemoHashButton, layout.NewSpacer())
authorLabel := widget.NewLabel("Author:")
authorIdentityHashString, _, err := identity.EncodeIdentityHashBytesToString(authorIdentityHash)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
authorIdentityHashTrimmed, _, err := helpers.TrimAndFlattenString(authorIdentityHashString, 15)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
authorIdentityHashLabel := getBoldLabel(authorIdentityHashTrimmed)
viewIdentityHashButton := widget.NewButtonWithIcon("", theme.VisibilityIcon(), func(){
setViewIdentityHashPage(window, authorIdentityHash, currentPage)
})
authorRow := container.NewHBox(layout.NewSpacer(), authorLabel, authorIdentityHashLabel, viewIdentityHashButton, layout.NewSpacer())
viewCryptocurrencyAddressesButton := getWidgetCentered(widget.NewButtonWithIcon("View Cryptocurrency Addresses", theme.VisibilityIcon(), func(){
setViewMemoCryptocurrencyAddressesPage(window, memoHash, "Ethereum", currentPage)
}))
viewUnarmoredContentsButton := getWidgetCentered(widget.NewButtonWithIcon("View Unarmored Contents", theme.VisibilityIcon(), func(){
setViewTextPage(window, "Viewing Memo Unarmored Contents", memoUnarmoredContents, true, currentPage)
}))
page := container.NewVBox(title, backButton, widget.NewSeparator(), description, widget.NewSeparator(), memoHashRow, authorRow, viewCryptocurrencyAddressesButton, viewUnarmoredContentsButton)
setPageContent(page, window)
}