2024-04-11 15:51:56 +02:00
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 ( ) {
2024-06-03 04:42:45 +02:00
setCreateCustomIdentityHashPage ( window , identityType , false , 0 , 0 , currentPage , submitPage )
2024-04-11 15:51:56 +02:00
} )
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 )
}