737 lines
27 KiB
Go
737 lines
27 KiB
Go
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)
|
|
}
|
|
|
|
|