seekia/gui/matchesGui.go

2159 lines
74 KiB
Go

package gui
// matchesGui.go implements pages to view a user's mate matches
import "fyne.io/fyne/v2"
import "fyne.io/fyne/v2/canvas"
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/appMemory"
import "seekia/internal/badgerDatabase"
import "seekia/internal/desires/mateDesires"
import "seekia/internal/desires/myLocalDesires"
import "seekia/internal/desires/myMateDesires"
import "seekia/internal/encoding"
import "seekia/internal/helpers"
import "seekia/internal/identity"
import "seekia/internal/imagery"
import "seekia/internal/myBlockedUsers"
import "seekia/internal/myIdentity"
import "seekia/internal/myIgnoredUsers"
import "seekia/internal/myLikedUsers"
import "seekia/internal/myMatches"
import "seekia/internal/myMatchScore"
import "seekia/internal/mySettings"
import "seekia/internal/network/appNetworkType/getAppNetworkType"
import "seekia/internal/profiles/attributeDisplay"
import "seekia/internal/profiles/viewableProfiles"
import "strings"
import "time"
import "errors"
import "slices"
import "sync"
func setMatchesPage(window fyne.Window){
appMemory.SetMemoryEntry("CurrentViewedPage", "Matches")
checkIfPageHasChangedFunction := func()bool{
exists, currentViewedPage := appMemory.GetMemoryEntry("CurrentViewedPage")
if (exists == false || currentViewedPage != "Matches"){
return true
}
return false
}
currentPage := func(){setMatchesPage(window)}
title := getPageTitleCentered("My Matches")
desiresIcon, err := getFyneImageIcon("Desires")
if (err != nil){
setErrorEncounteredPage(window, err, func(){setHomePage(window)})
return
}
statsIcon, err := getFyneImageIcon("Stats")
if (err != nil){
setErrorEncounteredPage(window, err, func(){setHomePage(window)})
return
}
matchScoreIcon, err := getFyneImageIcon("MatchScore")
if (err != nil){
setErrorEncounteredPage(window, err, func(){setHomePage(window)})
return
}
customizeIcon, err := getFyneImageIcon("Info")
if (err != nil){
setErrorEncounteredPage(window, err, func(){setHomePage(window)})
return
}
desiresButton := widget.NewButton(translate("Desires"), func(){
setViewAllMyDesiresPage(window, currentPage)
})
desiresButtonWithIcon := container.NewGridWithColumns(1, desiresIcon, desiresButton)
customizeButton := widget.NewButton("Customize", func(){
setCustomizeMatchDisplayPage(window, currentPage)
})
customizeButtonWithIcon := container.NewGridWithColumns(1, customizeIcon, customizeButton)
matchScoreButton := widget.NewButton(translate("Score"), func(){
setConfigureMatchScorePage(window, currentPage)
})
matchScoreButtonWithIcon := container.NewGridWithColumns(1, matchScoreIcon, matchScoreButton)
statsButton := widget.NewButton(translate("Stats"), func(){
setMyMatchStatisticsPage(window, currentPage)
})
statsButtonWithIcon := container.NewGridWithColumns(1, statsIcon, statsButton)
buttonsRow := getContainerCentered(container.NewGridWithRows(1, matchScoreButtonWithIcon, desiresButtonWithIcon, statsButtonWithIcon, customizeButtonWithIcon))
currentSortByAttribute, err := myMatches.GetMatchesSortByAttribute()
if (err != nil) {
setErrorEncounteredPage(window, err, func(){setHomePage(window)})
return
}
sortingByLabel := getBoldLabel(translate("Sorting By:"))
sortByAttributeTitle, _, _, _, _, err := attributeDisplay.GetProfileAttributeDisplayInfo(currentSortByAttribute)
if (err != nil){
setErrorEncounteredPage(window, err, func(){setHomePage(window)})
return
}
sortByButton := widget.NewButton(translate(sortByAttributeTitle), func(){
setSelectMatchesSortByAttributePage(window, currentPage)
})
getSortDirectionButtonWithIcon := func()(fyne.Widget, error){
currentSortDirection, err := myMatches.GetMatchesSortDirection()
if (err != nil) { return nil, err }
if (currentSortDirection == "Ascending"){
ascendingButton := widget.NewButtonWithIcon(translate("Ascending"), theme.MoveUpIcon(), func(){
appMemory.SetMemoryEntry("StopBuildMatchesYesNo", "Yes")
_ = mySettings.SetSetting("MatchesSortDirection", "Descending")
_ = mySettings.SetSetting("MatchesSortedStatus", "No")
_ = mySettings.SetSetting("MatchesViewIndex", "0")
currentPage()
})
return ascendingButton, nil
}
descendingButton := widget.NewButtonWithIcon(translate("Descending"), theme.MoveDownIcon(), func(){
appMemory.SetMemoryEntry("StopBuildMatchesYesNo", "Yes")
_ = mySettings.SetSetting("MatchesSortDirection", "Ascending")
_ = mySettings.SetSetting("MatchesSortedStatus", "No")
_ = mySettings.SetSetting("MatchesViewIndex", "0")
currentPage()
})
return descendingButton, nil
}
sortDirectionButton, err := getSortDirectionButtonWithIcon()
if (err != nil) {
setErrorEncounteredPage(window, err, func(){setHomePage(window)})
return
}
sortByRow := container.NewHBox(layout.NewSpacer(), sortingByLabel, sortByButton, sortDirectionButton, layout.NewSpacer())
appNetworkType, err := getAppNetworkType.GetAppNetworkType()
if (err != nil) {
setErrorEncounteredPage(window, err, func(){setHomePage(window)})
return
}
matchesReady, err := myMatches.GetMatchesReadyStatus(appNetworkType)
if (err != nil) {
setErrorEncounteredPage(window, err, func(){setHomePage(window)})
return
}
if (matchesReady == false){
progressPercentageBinding := binding.NewFloat()
sortingProgressBinding := binding.NewString()
startUpdateMatchesAndProgressBarFunction := func(){
err := myMatches.StartUpdatingMyMatches(appNetworkType)
if (err != nil) {
setErrorEncounteredPage(window, err, currentPage)
return
}
sortingProgressBindingSet := false
var encounteredError error
for {
pageHasChanged := checkIfPageHasChangedFunction()
if (pageHasChanged == true){
appMemory.SetMemoryEntry("StopBuildMatchesYesNo", "Yes")
return
}
buildEncounteredError, errorEncounteredString, buildIsStopped, matchesAreReady, currentPercentageProgress, err := myMatches.GetMyMatchesBuildStatus(appNetworkType)
if (err != nil){
encounteredError = err
break
}
if (buildEncounteredError == true){
encounteredError = errors.New(errorEncounteredString)
break
}
if (buildIsStopped == true){
return
}
if (matchesAreReady == true){
progressPercentageBinding.Set(1)
// We wait so that the loading bar will appear complete.
time.Sleep(100 * time.Millisecond)
currentPage()
return
}
progressPercentageBinding.Set(currentPercentageProgress)
if (currentPercentageProgress >= .50 && sortingProgressBindingSet == false){
numberOfMatches, err := myMatches.GetNumberOfGeneratedMatches()
if (err != nil) {
encounteredError = err
break
}
if (numberOfMatches != 0){
numberOfMatchesString := helpers.ConvertIntToString(numberOfMatches)
sortingProgressBinding.Set("Sorting " + numberOfMatchesString + " Matches...")
}
sortingProgressBindingSet = true
}
time.Sleep(100 * time.Millisecond)
}
// This will only be reached if an error occurred
errorToShow := errors.New("Error encountered while generating matches: " + encounteredError.Error())
setErrorEncounteredPage(window, errorToShow, currentPage)
}
loadingLabel := getBoldLabelCentered("Loading Matches...")
loadingBar := getWidgetCentered(widget.NewProgressBarWithData(progressPercentageBinding))
loadingDetailsLabel := widget.NewLabelWithData(sortingProgressBinding)
loadingDetailsLabel.TextStyle = getFyneTextStyle_Italic()
loadingDetailsLabelCentered := getWidgetCentered(loadingDetailsLabel)
page := container.NewVBox(title, widget.NewSeparator(), buttonsRow, widget.NewSeparator(), sortByRow, widget.NewSeparator(), loadingLabel, loadingBar, loadingDetailsLabelCentered)
setPageContent(page, window)
go startUpdateMatchesAndProgressBarFunction()
return
}
getSplashContainer := func()(*fyne.Container, error){
getRefreshResultsButtonText := func()(string, error){
needsRefresh, err := myMatches.CheckIfMyMatchesNeedRefresh()
if (err != nil) { return "", err }
if (needsRefresh == false){
return "Refresh Results", nil
}
return "Refresh Results - Updates Available!", nil
}
refreshButtonText, err := getRefreshResultsButtonText()
if (err != nil){ return nil, err }
refreshResultsButton := getWidgetCentered(widget.NewButtonWithIcon(refreshButtonText, theme.ViewRefreshIcon(), func(){
_ = mySettings.SetSetting("MatchesGeneratedStatus", "No")
_ = mySettings.SetSetting("MatchesViewIndex", "0")
currentPage()
}))
matchesReady, currentMatchesList, err := myMatches.GetMyMatchesList(appNetworkType)
if (err != nil) { return nil, err }
if (matchesReady == false){
// This should not happen, as matches were found to be ready already.
return nil, errors.New("Matches not ready after being ready already.")
}
if (len(currentMatchesList) == 0){
noMatchesFoundLabel := getBoldLabelCentered("No Matches Found")
description1 := getLabelCentered("Edit your desires to find more matches.")
description2 := getLabelCentered("View your desire statistics to see which desires are reducing your matches.")
viewDesireStatisticsButton := getWidgetCentered(widget.NewButtonWithIcon("View Desire Statistics", theme.VisibilityIcon(), func(){
setMyMatchStatisticsPage(window, currentPage)
}))
noMatchesFoundContainer := container.NewVBox(noMatchesFoundLabel, refreshResultsButton, widget.NewSeparator(), description1, description2, viewDesireStatisticsButton)
return noMatchesFoundContainer, nil
}
numberOfMatches := len(currentMatchesList)
numberOfMatchesString := helpers.ConvertIntToString(numberOfMatches)
getNumberOfMatchesFoundText := func()string{
if (numberOfMatches == 1){
result := translate("1 Match Found")
return result
}
result := numberOfMatchesString + " " + translate("Matches Found")
return result
}
numberOfMatchesFoundText := getNumberOfMatchesFoundText()
numberOfMatchesFoundLabel := getBoldLabelCentered(numberOfMatchesFoundText)
getBeginRestartContinueButtons := func()(*fyne.Container, error){
getMatchesViewIndex := func()(int, error){
exists, currentIndex, err := mySettings.GetSetting("MatchesViewIndex")
if (err != nil) { return 0, err }
if (exists == false){
return 0, nil
}
currentIndexInt, err := helpers.ConvertStringToInt(currentIndex)
if (err != nil) { return 0, err }
if (currentIndexInt > (numberOfMatches-1)){
return 0, nil
}
return currentIndexInt, nil
}
currentViewIndex, err := getMatchesViewIndex()
if (err != nil) { return nil, err }
if (currentViewIndex == 0){
beginButton := getWidgetCentered(widget.NewButtonWithIcon("Begin Browsing", theme.NavigateNextIcon(), func(){
setBrowseMatchesPage(window, currentPage)
}))
return beginButton, nil
}
restartButton := getWidgetCentered(widget.NewButtonWithIcon("Restart From Beginning", theme.ContentUndoIcon(), func(){
mySettings.SetSetting("MatchesViewIndex", "0")
setBrowseMatchesPage(window, currentPage)
}))
currentViewIndexString := helpers.ConvertIntToString(currentViewIndex + 1)
continueButtonText := "Continue from profile " + currentViewIndexString + " of " + numberOfMatchesString
continueButton := getWidgetCentered(widget.NewButtonWithIcon(continueButtonText, theme.MailForwardIcon(), func(){
setBrowseMatchesPage(window, currentPage)
}))
buttons := container.NewVBox(restartButton, continueButton)
return buttons, nil
}
beginRestartContinueButtons, err := getBeginRestartContinueButtons()
if (err != nil) { return nil, err }
splashPageContent := container.NewVBox(numberOfMatchesFoundLabel, widget.NewSeparator(), beginRestartContinueButtons, refreshResultsButton)
return splashPageContent, nil
}
splashContainer, err := getSplashContainer()
if (err != nil){
setErrorEncounteredPage(window, err, func(){setHomePage(window)})
return
}
page := container.NewVBox(title, widget.NewSeparator(), buttonsRow, widget.NewSeparator(), sortByRow, widget.NewSeparator(), splashContainer)
setPageContent(page, window)
}
// This page should only be called if matches are ready and at least 1 exists
func setBrowseMatchesPage(window fyne.Window, previousPage func()){
currentPage := func(){setBrowseMatchesPage(window, previousPage)}
title := getPageTitleCentered("Browse Matches")
backButton := getBackButtonCentered(previousPage)
getPageContent := func()(*fyne.Container, error){
appNetworkType, err := getAppNetworkType.GetAppNetworkType()
if (err != nil) { return nil, err }
matchesReady, currentMatchesList, err := myMatches.GetMyMatchesList(appNetworkType)
if (err != nil) { return nil, err }
if (matchesReady == false) {
// This should not happen, because this page should only be called if matches are already ready
return nil, errors.New("setBrowseMatchesPage called when matches are not ready.")
}
if (len(currentMatchesList) == 0){
return nil, errors.New("setBrowseMatchesPage called with no matches found.")
}
numberOfMatches := len(currentMatchesList)
getViewIndex := func()(int, error){
exists, currentIndexString, err := mySettings.GetSetting("MatchesViewIndex")
if (err != nil) { return 0, err }
if (exists == false){
return 0, nil
}
currentIndex, err := helpers.ConvertStringToInt(currentIndexString)
if (err != nil){
return 0, errors.New("MySettings malformed: Contains invalid MatchesViewIndex: " + currentIndexString)
}
if (currentIndex < 0){
return 0, nil
}
maximumIndex := numberOfMatches-1
if (currentIndex > maximumIndex){
return maximumIndex, nil
}
return currentIndex, nil
}
currentIndex, err := getViewIndex()
if (err != nil) { return nil, err }
pageContent := container.NewVBox()
if (numberOfMatches > 1){
getNavigationButtons := func() *fyne.Container{
getGoToBeginningButton := func()fyne.Widget{
if (currentIndex == 0){
emptyButton := widget.NewButton("", nil)
return emptyButton
}
goToBeginningButton := widget.NewButtonWithIcon("", theme.MediaSkipPreviousIcon(), func(){
_ = mySettings.SetSetting("MatchesViewIndex", "0")
currentPage()
})
return goToBeginningButton
}
getGoToEndButton := func()fyne.Widget{
finalIndex := numberOfMatches - 1
if (currentIndex >= finalIndex){
emptyButton := widget.NewButton("", nil)
return emptyButton
}
goToEndButton := widget.NewButtonWithIcon("", theme.MediaSkipNextIcon(), func(){
finalIndexString := helpers.ConvertIntToString(finalIndex)
_ = mySettings.SetSetting("MatchesViewIndex", finalIndexString)
currentPage()
})
return goToEndButton
}
getLeftButton := func()fyne.Widget{
if (currentIndex == 0){
emptyButton := widget.NewButton("", nil)
return emptyButton
}
leftButton := widget.NewButtonWithIcon("", theme.NavigateBackIcon(), func(){
newIndex := helpers.ConvertIntToString(currentIndex-1)
_ = mySettings.SetSetting("MatchesViewIndex", newIndex)
currentPage()
})
return leftButton
}
getRightButton := func()fyne.Widget{
finalIndex := numberOfMatches - 1
if (currentIndex >= finalIndex){
emptyButton := widget.NewButton("", nil)
return emptyButton
}
rightButton := widget.NewButtonWithIcon("", theme.NavigateNextIcon(), func(){
newIndex := helpers.ConvertIntToString(currentIndex+1)
_ = mySettings.SetSetting("MatchesViewIndex", newIndex)
currentPage()
})
return rightButton
}
goToBeginningButton := getGoToBeginningButton()
goToEndButton := getGoToEndButton()
leftButton := getLeftButton()
rightButton := getRightButton()
if (numberOfMatches == 1){
buttons := getContainerCentered(container.NewGridWithRows(1, goToBeginningButton, leftButton, rightButton, goToEndButton))
return buttons
}
matchRank := currentIndex + 1
currentRankString := helpers.ConvertIntToString(matchRank)
numberOfMatchesString := helpers.ConvertIntToString(numberOfMatches)
currentRankDescription := getBoldLabel(currentRankString + "/" + numberOfMatchesString)
buttons := getContainerCentered(container.NewGridWithRows(1, goToBeginningButton, leftButton, currentRankDescription, rightButton, goToEndButton))
return buttons
}
navButtons := getNavigationButtons()
pageContent.Add(navButtons)
pageContent.Add(widget.NewSeparator())
}
getMatchDisplay := func()(*fyne.Container, error){
if (currentIndex >= len(currentMatchesList) || currentIndex < 0){
return nil, errors.New("Match index out of range.")
}
matchIdentityHash := currentMatchesList[currentIndex]
userIsBlocked, _, _, _, err := myBlockedUsers.CheckIfUserIsBlocked(matchIdentityHash)
if (err != nil) { return nil, err }
if (userIsBlocked == true){
isBlockedDescription1 := getBoldLabelCentered("User is blocked.")
isBlockedDescription2 := getLabelCentered("You have blocked this match.")
isBlockedDescription3 := getLabelCentered("Refresh your matches to fix this.")
refreshMatchesButton := getWidgetCentered(widget.NewButtonWithIcon("Refresh Matches", theme.ViewRefreshIcon(), func(){
_ = mySettings.SetSetting("MatchesGeneratedStatus", "No")
_ = mySettings.SetSetting("MatchesViewIndex", "0")
setMatchesPage(window)
}))
userIsBlockedSection := container.NewVBox(isBlockedDescription1, isBlockedDescription2, isBlockedDescription3, refreshMatchesButton)
return userIsBlockedSection, nil
}
getShowIgnoredMatchesBool := func()(bool, error){
exists, isIgnoredIsEnabled, err := myLocalDesires.GetDesire("IsIgnored_FilterAll")
if (err != nil) { return false, err }
if (exists == false){
// Desire is disabled.
return true, nil
}
if (isIgnoredIsEnabled == "No"){
// Desire is disabled.
// We will show ignored matches
return true, nil
}
exists, isIgnoredDesire, err := myLocalDesires.GetDesire("IsIgnored")
if (err != nil) { return false, err }
if (exists == false){
// Desire does not exist.
// We will show ignored matches
return true, nil
}
// isIgnoredDesire is a list of base64 encoded values which the user wants
// We see if "Yes" is contained within the list
// If it is not, then the user desires only non-ignored users
myDesiredChoicesList := strings.Split(isIgnoredDesire, "+")
yesBase64 := encoding.EncodeBytesToBase64String([]byte("Yes"))
yesExists := slices.Contains(myDesiredChoicesList, yesBase64)
if (yesExists == true){
// We want to see ignored users in our matches
return true, nil
}
return false, nil
}
showIgnoredMatchesBool, err := getShowIgnoredMatchesBool()
if (err != nil) { return nil, err }
userIsIgnored, _, _, _, err := myIgnoredUsers.CheckIfUserIsIgnored(matchIdentityHash)
if (err != nil) { return nil, err }
if (userIsIgnored == true && showIgnoredMatchesBool == false){
isIgnoredDescription1 := getBoldLabelCentered("User is ignored.")
isIgnoredDescription2 := getLabelCentered("You have ignored this match.")
isIgnoredDescription3 := getLabelCentered("Refresh your matches to fix this.")
refreshMatchesButton := getWidgetCentered(widget.NewButtonWithIcon("Refresh Matches", theme.ViewRefreshIcon(), func(){
_ = mySettings.SetSetting("MatchesGeneratedStatus", "No")
_ = mySettings.SetSetting("MatchesViewIndex", "0")
setMatchesPage(window)
}))
userIsIgnoredSection := container.NewVBox(isIgnoredDescription1, isIgnoredDescription2, isIgnoredDescription3, refreshMatchesButton)
return userIsIgnoredSection, nil
}
profileExists, _, getAnyAttributeFunction, err := viewableProfiles.GetRetrieveAnyNewestViewableUserProfileAttributeFunction(matchIdentityHash, appNetworkType, true, false, true)
if (err != nil) { return nil, err }
if (profileExists == false) {
matchNotFoundLabel := getBoldLabelCentered("Match Not Found")
description1 := getLabelCentered("Their profile may have been deleted.")
description2 := getLabelCentered("Refresh your matches to fix this.")
refreshMatchesButton := getWidgetCentered(widget.NewButtonWithIcon("Refresh Matches", theme.ViewRefreshIcon(), func(){
_ = mySettings.SetSetting("MatchesGeneratedStatus", "No")
_ = mySettings.SetSetting("MatchesViewIndex", "0")
setMatchesPage(window)
}))
matchNotFoundSection := container.NewVBox(matchNotFoundLabel, description1, description2, refreshMatchesButton)
return matchNotFoundSection, nil
}
exists, _, userIsDisabled, err := getAnyAttributeFunction("Disabled")
if (err != nil){ return nil, err }
if (exists == true && userIsDisabled == "Yes"){
matchIsDisabledLabel := getBoldLabelCentered("User Is Disabled")
description1 := getLabelCentered("This user has disabled their profile.")
description2 := getLabelCentered("Refresh your matches to fix this.")
refreshMatchesButton := getWidgetCentered(widget.NewButtonWithIcon("Refresh Matches", theme.ViewRefreshIcon(), func(){
_ = mySettings.SetSetting("MatchesGeneratedStatus", "No")
_ = mySettings.SetSetting("MatchesViewIndex", "0")
setMatchesPage(window)
}))
matchIsDisabledSection := container.NewVBox(matchIsDisabledLabel, description1, description2, refreshMatchesButton)
return matchIsDisabledSection, nil
}
// We see if user's newest viewable profile still fulfills our desires
profilePassesDesires, err := myMateDesires.CheckIfMateProfilePassesAllMyDesires(false, "", getAnyAttributeFunction)
if (err != nil) { return nil, err }
if (profilePassesDesires == false){
userIsNotAMatchLabel := getBoldLabelCentered("User Is Not A Match Anymore")
description1 := getLabelCentered("This user has changed their profile and they are no longer a match.")
description2 := getLabelCentered("Refresh your matches to fix this.")
refreshMatchesButton := getWidgetCentered(widget.NewButtonWithIcon("Refresh Matches", theme.ViewRefreshIcon(), func(){
_ = mySettings.SetSetting("MatchesGeneratedStatus", "No")
_ = mySettings.SetSetting("MatchesViewIndex", "0")
setMatchesPage(window)
}))
userIsNotAMatchSection := container.NewVBox(userIsNotAMatchLabel, description1, description2, refreshMatchesButton)
return userIsNotAMatchSection, nil
}
getAvatarOrImage := func()(*canvas.Image, error){
photosExist, _, photosAttribute, err := getAnyAttributeFunction("Photos")
if (err != nil) { return nil, err }
if (photosExist == true){
photosList := strings.Split(photosAttribute, "+")
firstPhotoBase64String := photosList[0]
goImageObject, err := imagery.ConvertWEBPBase64StringToCroppedDownsizedImageObject(firstPhotoBase64String)
if (err != nil) {
return nil, errors.New("Database corrupt: Contains profile with invalid Photos attribute")
}
fyneImageObject := canvas.NewImageFromImage(goImageObject)
fyneImageObject.FillMode = canvas.ImageFillContain
return fyneImageObject, nil
}
getAvatarEmojiIdentifier := func()(int, error){
exists, _, emojiIdentifier, err := getAnyAttributeFunction("Avatar")
if (err != nil){ return 0, err }
if (exists == false){
// This is the avatar for users who have not selected an avatar
return 2929, nil
}
emojiIdentifierInt, err := helpers.ConvertStringToInt(emojiIdentifier)
if (err != nil) {
return 0, errors.New("Database corrupt: Contains user profile with invalid avatar: " + emojiIdentifier)
}
return emojiIdentifierInt, nil
}
avatarEmojiIdentifier, err := getAvatarEmojiIdentifier()
if (err != nil) { return nil, err }
emojiImage, err := getEmojiImageObject(avatarEmojiIdentifier)
if (err != nil){ return nil, err }
emojiFyneImage := canvas.NewImageFromImage(emojiImage)
emojiFyneImage.FillMode = canvas.ImageFillContain
return emojiFyneImage, nil
}
avatarOrImage, err := getAvatarOrImage()
if (err != nil) { return nil, err }
avatarOrImage.SetMinSize(getCustomFyneSize(10))
avatarOrImageHeightenerA := container.NewVBox(widget.NewLabel(""), widget.NewLabel(""), widget.NewLabel(""))
avatarOrImageHeightenerB := container.NewVBox(widget.NewLabel(""), widget.NewLabel(""), widget.NewLabel(""))
avatarOrImageHeightened := getContainerCentered(container.NewGridWithRows(1, avatarOrImageHeightenerA, avatarOrImage, avatarOrImageHeightenerB))
viewProfileButton := getWidgetCentered(widget.NewButtonWithIcon("View Profile", theme.VisibilityIcon(), func(){
setViewPeerProfilePageFromIdentityHash(window, matchIdentityHash, currentPage)
}))
getAttributesSection := func()(*fyne.Container, error){
getDisplayAttributesList := func()([]string, error){
// First attribute is always the "Sort By" attribute
currentSortByAttribute, err := myMatches.GetMatchesSortByAttribute()
if (err != nil) { return nil, err }
exists, currentAttributesListString, err := mySettings.GetSetting("CustomMatchDisplayAttributesList")
if (err != nil) { return nil, err }
if (exists == false){
newDisplayAttributesList := []string{currentSortByAttribute}
return newDisplayAttributesList, nil
}
currentAttributesList := strings.Split(currentAttributesListString, ",")
displayAttributesListPruned, _ := helpers.DeleteAllMatchingItemsFromList(currentAttributesList, currentSortByAttribute)
newDisplayAttributesList := []string{currentSortByAttribute}
newDisplayAttributesList = append(newDisplayAttributesList, displayAttributesListPruned...)
return newDisplayAttributesList, nil
}
displayAttributesList, err := getDisplayAttributesList()
if (err != nil){ return nil, err }
attributesSection := container.NewVBox()
for _, attributeName := range displayAttributesList{
attributeTitle, _, formatValueFunction, attributeUnits, missingValueText, err := attributeDisplay.GetProfileAttributeDisplayInfo(attributeName)
if (err != nil) { return nil, err }
attributeTitleLabel := getBoldLabel(attributeTitle + ":")
getAttributeValueText := func()(string, error){
attributeValueExists, _, attributeValue, err := getAnyAttributeFunction(attributeName)
if (err != nil) { return "", err }
if (attributeValueExists == false){
return missingValueText, nil
}
formattedValue, err := formatValueFunction(attributeValue)
if (err != nil) { return "", err }
result := formattedValue + attributeUnits
return result, nil
}
attributeValueText, err := getAttributeValueText()
if (err != nil) { return nil, err }
attributeValueLabel := widget.NewLabel(attributeValueText)
attributeRow := container.NewHBox(layout.NewSpacer(), attributeTitleLabel, attributeValueLabel, layout.NewSpacer())
attributesSection.Add(attributeRow)
}
return attributesSection, nil
}
attributesSection, err := getAttributesSection()
if (err != nil) { return nil, err }
getLikeOrUnlikeButtonWithIcon := func()(*fyne.Container, error){
userIsLiked, _, err := myLikedUsers.CheckIfUserIsLiked(matchIdentityHash)
if (err != nil) { return nil, err }
if (userIsLiked == true){
unlikeIcon, err := getFyneImageIcon("Unlike")
if (err != nil) { return nil, err }
unlikeButton := widget.NewButton("Unlike", func(){
setConfirmUnlikeUserPage(window, matchIdentityHash, currentPage, currentPage)
})
unlikeButtonWithIcon := container.NewGridWithColumns(1, unlikeIcon, unlikeButton)
return unlikeButtonWithIcon, nil
}
likeIcon, err := getFyneImageIcon("Like")
if (err != nil) { return nil, err }
likeButton := widget.NewButton("Like", func(){
setConfirmLikeUserPage(window, matchIdentityHash, currentPage, currentPage)
})
likeButtonWithIcon := container.NewGridWithColumns(1, likeIcon, likeButton)
return likeButtonWithIcon, nil
}
likeOrUnlikeButtonWithIcon, err := getLikeOrUnlikeButtonWithIcon()
if (err != nil) { return nil, err }
getIgnoreOrUnignoreButtonWithIcon := func()(*fyne.Container, error){
if (userIsIgnored == true){
unignoreIcon := widget.NewIcon(theme.VisibilityIcon())
unignoreButton := widget.NewButton("Unignore", func(){
setConfirmUnignoreUserPage(window, matchIdentityHash, currentPage, currentPage)
})
unignoreButtonWithIcon := container.NewGridWithColumns(1, unignoreIcon, unignoreButton)
return unignoreButtonWithIcon, nil
}
ignoreIcon := widget.NewIcon(theme.VisibilityOffIcon())
ignoreButton := widget.NewButton("Ignore", func(){
setConfirmIgnoreUserPage(window, matchIdentityHash, currentPage, currentPage)
})
ignoreButtonWithIcon := container.NewGridWithColumns(1, ignoreIcon, ignoreButton)
return ignoreButtonWithIcon, nil
}
ignoreOrUnignoreButtonWithIcon, err := getIgnoreOrUnignoreButtonWithIcon()
if (err != nil) { return nil, err }
greetIcon, err := getFyneImageIcon("Greet")
if (err != nil) { return nil, err }
greetButton := widget.NewButton("Greet", func(){
setConfirmGreetOrRejectUserPage(window, "Greet", matchIdentityHash, currentPage, currentPage)
})
greetButtonWithIcon := container.NewGridWithColumns(1, greetIcon, greetButton)
moreIcon, err := getFyneImageIcon("Plus")
if (err != nil) { return nil, err }
moreButton := widget.NewButton("More", func(){
setViewPeerActionsPage(window, matchIdentityHash, currentPage)
})
moreButtonWithIcon := container.NewGridWithColumns(1, moreIcon, moreButton)
actionsRow := getContainerCentered(container.NewGridWithRows(1, likeOrUnlikeButtonWithIcon, ignoreOrUnignoreButtonWithIcon, greetButtonWithIcon, moreButtonWithIcon))
matchDisplay := container.NewVBox(avatarOrImageHeightened, viewProfileButton, widget.NewSeparator(), attributesSection, widget.NewSeparator(), actionsRow)
return matchDisplay, nil
}
matchDisplay, err := getMatchDisplay()
if (err != nil) { return nil, err }
pageContent.Add(matchDisplay)
return pageContent, nil
}
pageContent, err := getPageContent()
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
page := container.NewVBox(title, backButton, widget.NewSeparator(), pageContent)
setPageContent(page, window)
}
func setSelectMatchesSortByAttributePage(window fyne.Window, previousPage func()){
appMemory.SetMemoryEntry("CurrentViewedPage", "SortBySelectPage_Matches")
title := getPageTitleCentered("Select Sort By Attribute")
backButton := getBackButtonCentered(previousPage)
description := getLabelCentered("Choose the attribute to sort your matches by.")
getPageContent := func()(*fyne.Container, error){
generalAttributeButtonsGrid := container.NewGridWithColumns(1)
physicalAttributeButtonsGrid := container.NewGridWithColumns(1)
lifestyleAttributeButtonsGrid := container.NewGridWithColumns(1)
mentalAttributeButtonsGrid := container.NewGridWithColumns(1)
addAttributeSelectButton := func(attributeType string, attributeName string, sortDirection string)error{
attributeTitle, _, _, _, _, err := attributeDisplay.GetProfileAttributeDisplayInfo(attributeName)
if (err != nil) { return err }
attributeButton := widget.NewButton(attributeTitle, func(){
_ = mySettings.SetSetting("MatchesSortedStatus", "No")
_ = mySettings.SetSetting("MatchesSortByAttribute", attributeName)
_ = mySettings.SetSetting("MatchesSortDirection", sortDirection)
_ = mySettings.SetSetting("MatchesViewIndex", "0")
previousPage()
})
if (attributeType == "General"){
generalAttributeButtonsGrid.Add(attributeButton)
} else if (attributeType == "Physical"){
physicalAttributeButtonsGrid.Add(attributeButton)
} else if (attributeType == "Lifestyle"){
lifestyleAttributeButtonsGrid.Add(attributeButton)
} else if (attributeType == "Mental"){
mentalAttributeButtonsGrid.Add(attributeButton)
} else {
return errors.New("addSelectButton called with invalid attributeType: " + attributeType)
}
return nil
}
generalLabel := getBoldLabelCentered("General")
err := addAttributeSelectButton("General", "MatchScore", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("General", "Distance", "Ascending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("General", "SearchTermsCount", "Descending")
if (err != nil) { return nil, err }
physicalLabel := getBoldLabelCentered("Physical")
err = addAttributeSelectButton("Physical", "Age", "Ascending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "Height", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "BodyFat", "Ascending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "BodyMuscle", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "SkinColor", "Ascending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "HairTexture", "Ascending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "RacialSimilarity", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "EyeColorSimilarity", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "EyeColorGenesSimilarity", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "HairColorSimilarity", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "HairColorGenesSimilarity", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "SkinColorSimilarity", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "SkinColorGenesSimilarity", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "HairTextureSimilarity", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "HairTextureGenesSimilarity", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "FacialStructureGenesSimilarity", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "23andMe_AncestralSimilarity", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "23andMe_MaternalHaplogroupSimilarity", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "23andMe_PaternalHaplogroupSimilarity", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "OffspringProbabilityOfAnyMonogenicDisease", "Ascending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "TotalPolygenicDiseaseRiskScore", "Ascending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "OffspringTotalPolygenicDiseaseRiskScore", "Ascending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "AutismRiskScore", "Ascending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "OffspringAutismRiskScore", "Ascending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "ObesityRiskScore", "Ascending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "OffspringObesityRiskScore", "Ascending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "OffspringBlueEyesProbability", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "OffspringGreenEyesProbability", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "OffspringHazelEyesProbability", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "OffspringBrownEyesProbability", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "OffspringLactoseToleranceProbability", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "OffspringStraightHairProbability", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "OffspringCurlyHairProbability", "Descending")
if (err != nil) { return nil, err }
// Numeric Traits:
err = addAttributeSelectButton("Physical", "HomosexualnessScore", "Ascending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "OffspringHomosexualnessScore", "Ascending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "PredictedHeight", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "OffspringPredictedHeight", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Physical", "23andMe_NeanderthalVariants", "Descending")
if (err != nil) { return nil, err }
lifestyleLabel := getBoldLabelCentered("Lifestyle")
err = addAttributeSelectButton("Lifestyle", "WealthInGold", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Lifestyle", "Fame", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Lifestyle", "FruitRating", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Lifestyle", "VegetablesRating", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Lifestyle", "NutsRating", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Lifestyle", "GrainsRating", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Lifestyle", "DairyRating", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Lifestyle", "SeafoodRating", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Lifestyle", "BeefRating", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Lifestyle", "PorkRating", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Lifestyle", "PoultryRating", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Lifestyle", "EggsRating", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Lifestyle", "BeansRating", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Lifestyle", "AlcoholFrequency", "Ascending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Lifestyle", "TobaccoFrequency", "Ascending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Lifestyle", "CannabisFrequency", "Ascending")
if (err != nil) { return nil, err }
mentalLabel := getBoldLabelCentered("Mental")
err = addAttributeSelectButton("Mental", "PetsRating", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Mental", "CatsRating", "Descending")
if (err != nil) { return nil, err }
err = addAttributeSelectButton("Mental", "DogsRating", "Descending")
if (err != nil) { return nil, err }
generalAttributeButtonsGridCentered := getContainerCentered(generalAttributeButtonsGrid)
physicalAttributeButtonsGridCentered := getContainerCentered(physicalAttributeButtonsGrid)
lifestyleAttributeButtonsGridCentered := getContainerCentered(lifestyleAttributeButtonsGrid)
mentalAttributeButtonsGridCentered := getContainerCentered(mentalAttributeButtonsGrid)
pageContent := container.NewVBox(generalLabel, widget.NewSeparator(), generalAttributeButtonsGridCentered, widget.NewSeparator(), physicalLabel, widget.NewSeparator(), physicalAttributeButtonsGridCentered, widget.NewSeparator(), lifestyleLabel, widget.NewSeparator(), lifestyleAttributeButtonsGridCentered, widget.NewSeparator(), mentalLabel, widget.NewSeparator(), mentalAttributeButtonsGridCentered)
return pageContent, nil
}
pageContent, err := getPageContent()
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
page := container.NewVBox(title, backButton, widget.NewSeparator(), description, widget.NewSeparator(), pageContent)
setPageContent(page, window)
}
func setMyMatchStatisticsPage(window fyne.Window, previousPage func()){
pageIdentifier, err := helpers.GetNewRandomHexString(16)
if (err != nil) {
setErrorEncounteredPage(window, err, previousPage)
return
}
appMemory.SetMemoryEntry("CurrentViewedPage", pageIdentifier)
checkIfPageHasChangedFunction := func()bool{
exists, currentViewedPage := appMemory.GetMemoryEntry("CurrentViewedPage")
if (exists == true && currentViewedPage == pageIdentifier){
return false
}
return true
}
currentPage := func(){setMyMatchStatisticsPage(window, previousPage)}
title := getPageTitleCentered("My Match Statistics")
backButton := getBackButtonCentered(previousPage)
description := getLabelCentered("Below are statistics about your matches.")
accuracyWarningButton := getWidgetCentered(widget.NewButtonWithIcon("Statistics Warning", theme.WarningIcon(), func(){
setMateDesireStatisticsWarningPage(window, currentPage)
}))
totalMateUsersBinding := binding.NewString()
totalBlockedUsersBinding := binding.NewString()
numberOfMatchesBinding := binding.NewString()
matchPercentageBinding := binding.NewString()
totalMateUsersDescription := widget.NewLabel("Total Mate Users:")
totalMateUsersLabel := widget.NewLabelWithData(totalMateUsersBinding)
totalMateUsersLabel.TextStyle = getFyneTextStyle_Bold()
totalMateUsersRow := container.NewHBox(layout.NewSpacer(), totalMateUsersDescription, totalMateUsersLabel, layout.NewSpacer())
totalBlockedUsersDescription := widget.NewLabel("Total Blocked Users:")
totalBlockedUsersLabel := widget.NewLabelWithData(totalBlockedUsersBinding)
totalBlockedUsersLabel.TextStyle = getFyneTextStyle_Bold()
totalBlockedUsersRow := container.NewHBox(layout.NewSpacer(), totalBlockedUsersDescription, totalBlockedUsersLabel, layout.NewSpacer())
numberOfMatchesDescription := widget.NewLabel("Number of Matches:")
numberOfMatchesLabel := widget.NewLabelWithData(numberOfMatchesBinding)
numberOfMatchesLabel.TextStyle = getFyneTextStyle_Bold()
numberOfMatchesRow := container.NewHBox(layout.NewSpacer(), numberOfMatchesDescription, numberOfMatchesLabel, layout.NewSpacer())
matchPercentageDescription := widget.NewLabel("Match Percentage:")
matchPercentageLabel := widget.NewLabelWithData(matchPercentageBinding)
matchPercentageLabel.TextStyle = getFyneTextStyle_Bold()
matchPercentageRow := container.NewHBox(layout.NewSpacer(), matchPercentageDescription, matchPercentageLabel, layout.NewSpacer())
appNetworkType, err := getAppNetworkType.GetAppNetworkType()
if (err != nil) {
setErrorEncounteredPage(window, err, previousPage)
return
}
updateBindingsFunction := func(){
var resultsReadyBoolMutex sync.RWMutex
resultsReadyBool := false
updateBindingsWithLoadingText := func(){
secondsElapsed := 0
for{
resultsReadyBoolMutex.RLock()
resultsReady := resultsReadyBool
resultsReadyBoolMutex.RUnlock()
if (resultsReady == true){
return
}
pageHasChanged := checkIfPageHasChangedFunction()
if (pageHasChanged == true){
return
}
if (secondsElapsed % 3 == 0){
totalMateUsersBinding.Set("Loading.")
numberOfMatchesBinding.Set("Loading.")
matchPercentageBinding.Set("Loading.")
} else if (secondsElapsed %3 == 1){
totalMateUsersBinding.Set("Loading..")
numberOfMatchesBinding.Set("Loading..")
matchPercentageBinding.Set("Loading..")
} else {
totalMateUsersBinding.Set("Loading...")
numberOfMatchesBinding.Set("Loading...")
matchPercentageBinding.Set("Loading...")
}
time.Sleep(time.Second)
secondsElapsed += 1
}
}
go updateBindingsWithLoadingText()
updateBindingsWithResultFunction := func()error{
// We use below to make sure we do not count ourselves as a peer profile
myIdentityExists, myIdentityHash, err := myIdentity.GetMyIdentityHash("Mate")
if (err != nil) { return err }
mateIdentityHashesList, err := badgerDatabase.GetAllProfileIdentityHashes("Mate")
if (err != nil) { return err }
numberOfUsersWithEnabledViewableProfile := 0
numberOfBlockedUsers := 0
numberOfMatches := 0
for _, userIdentityHash := range mateIdentityHashesList{
if (myIdentityExists == true && userIdentityHash == myIdentityHash){
// We don't count ourselves as a potential match
continue
}
profileExists, _, getAnyUserProfileAttributeFunction, err := viewableProfiles.GetRetrieveAnyNewestViewableUserProfileAttributeFunction(userIdentityHash, appNetworkType, true, false, false)
if (err != nil) { return err }
if (profileExists == false) {
continue
}
exists, _, _, err := getAnyUserProfileAttributeFunction("Disabled")
if (err != nil) { return err }
if (exists == true){
// Profile is disabled
continue
}
numberOfUsersWithEnabledViewableProfile += 1
userIsBlocked, _, _, _, err := myBlockedUsers.CheckIfUserIsBlocked(userIdentityHash)
if (err != nil) { return err }
if (userIsBlocked == true){
numberOfBlockedUsers += 1
continue
}
passesMyDesires, err := myMateDesires.CheckIfMateProfilePassesAllMyDesires(false, "", getAnyUserProfileAttributeFunction)
if (err != nil) { return err }
if (passesMyDesires == true){
numberOfMatches += 1
}
}
resultsReadyBoolMutex.Lock()
resultsReadyBool = true
resultsReadyBoolMutex.Unlock()
getMatchPercentage := func()float64{
if (numberOfUsersWithEnabledViewableProfile == 0){
return 0
}
matchPercentage := (float64(numberOfMatches)/float64(numberOfUsersWithEnabledViewableProfile)) * 100
return matchPercentage
}
matchPercentage := getMatchPercentage()
totalUsersString := helpers.ConvertIntToString(numberOfUsersWithEnabledViewableProfile)
totalBlockedUsersString := helpers.ConvertIntToString(numberOfBlockedUsers)
numberOfMatchesString := helpers.ConvertIntToString(numberOfMatches)
matchPercentageString := helpers.ConvertFloat64ToStringRounded(matchPercentage, 1)
totalMateUsersBinding.Set(totalUsersString)
totalBlockedUsersBinding.Set(totalBlockedUsersString)
numberOfMatchesBinding.Set(numberOfMatchesString)
matchPercentageBinding.Set(matchPercentageString + "%")
return nil
}
err := updateBindingsWithResultFunction()
if (err != nil){
pageHasChanged := checkIfPageHasChangedFunction()
if (pageHasChanged == false){
setErrorEncounteredPage(window, err, previousPage)
}
}
}
viewAllDesireStatisticsButton := getWidgetCentered(widget.NewButtonWithIcon("View All My Desire Statistics", theme.VisibilityIcon(), func(){
setViewAllMyDesireStatisticsPage(window, false, 0, 0, nil, currentPage)
}))
page := container.NewVBox(title, backButton, widget.NewSeparator(), description, widget.NewSeparator(), accuracyWarningButton, widget.NewSeparator(), totalMateUsersRow, totalBlockedUsersRow, numberOfMatchesRow, matchPercentageRow, viewAllDesireStatisticsButton)
setPageContent(page, window)
go updateBindingsFunction()
}
func setCustomizeMatchDisplayPage(window fyne.Window, previousPage func()){
appMemory.SetMemoryEntry("CurrentViewedPage", "CustomizeMatchDisplay")
currentPage := func(){setCustomizeMatchDisplayPage(window, previousPage)}
title := getPageTitleCentered("Customize Match Display")
backButton := getBackButtonCentered(previousPage)
description1 := getLabelCentered("Select the attributes to show when browsing matches.")
description2 := getLabelCentered("A maximum of 5 attributes can be selected.")
getCustomDisplayAttributesList := func()([]string, error){
exists, currentAttributesListString, err := mySettings.GetSetting("CustomMatchDisplayAttributesList")
if (err != nil) { return nil, err }
if (exists == false){
emptyList := make([]string, 0)
return emptyList, nil
}
currentAttributesList := strings.Split(currentAttributesListString, ",")
return currentAttributesList, nil
}
customDisplayAttributesList, err := getCustomDisplayAttributesList()
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
addAttributeButton := getWidgetCentered(widget.NewButtonWithIcon("Add Attribute", theme.ContentAddIcon(), func(){
if (len(customDisplayAttributesList) >= 5){
dialogTitle := translate("Attribute Limit Reached.")
dialogMessageA := getLabelCentered("You can only select 5 attributes.")
dialogContent := container.NewVBox(dialogMessageA)
dialog.ShowCustom(dialogTitle, translate("Close"), dialogContent, window)
return
}
setAddAttributeToCustomMatchDisplayPage(window, currentPage, currentPage)
}))
if (len(customDisplayAttributesList) == 0){
noAttributesSelectedLabel := getBoldLabelCentered("No Attributes Selected")
page := container.NewVBox(title, backButton, widget.NewSeparator(), description1, description2, widget.NewSeparator(), noAttributesSelectedLabel, addAttributeButton)
setPageContent(page, window)
return
}
currentAttributesLabel := getItalicLabelCentered("Current Attributes:")
getCurrentAttributesGrid := func()(*fyne.Container, error){
attributeIndexesColumn := container.NewVBox()
attributeTitlesColumn := container.NewVBox()
attributeRemoveButtonsColumn := container.NewVBox()
for index, attributeName := range customDisplayAttributesList{
attributeIndexString := helpers.ConvertIntToString(index+1) + "."
attributeTitle, _, _, _, _, err := attributeDisplay.GetProfileAttributeDisplayInfo(attributeName)
if (err != nil) { return nil, err }
attributeIndexLabel := getBoldLabelCentered(attributeIndexString)
attributeTitleLabel := getBoldLabelCentered(attributeTitle)
deleteAttributeButton := widget.NewButtonWithIcon("", theme.DeleteIcon(), func(){
newAttributesList, _ := helpers.DeleteAllMatchingItemsFromList(customDisplayAttributesList, attributeName)
if (len(newAttributesList) == 0){
err := mySettings.DeleteSetting("CustomMatchDisplayAttributesList")
if (err != nil) {
setErrorEncounteredPage(window, err, currentPage)
return
}
currentPage()
return
}
newAttributesListString := strings.Join(newAttributesList, ",")
err := mySettings.SetSetting("CustomMatchDisplayAttributesList", newAttributesListString)
if (err != nil) {
setErrorEncounteredPage(window, err, currentPage)
return
}
currentPage()
})
attributeIndexesColumn.Add(attributeIndexLabel)
attributeTitlesColumn.Add(attributeTitleLabel)
attributeRemoveButtonsColumn.Add(deleteAttributeButton)
attributeIndexesColumn.Add(widget.NewSeparator())
attributeTitlesColumn.Add(widget.NewSeparator())
attributeRemoveButtonsColumn.Add(widget.NewSeparator())
}
attributesGrid := container.NewHBox(layout.NewSpacer(), attributeIndexesColumn, attributeTitlesColumn, attributeRemoveButtonsColumn, layout.NewSpacer())
return attributesGrid, nil
}
currentAttributesGrid, err := getCurrentAttributesGrid()
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
page := container.NewVBox(title, backButton, widget.NewSeparator(), description1, description2, widget.NewSeparator(), addAttributeButton, widget.NewSeparator(), currentAttributesLabel, currentAttributesGrid)
setPageContent(page, window)
}
func setAddAttributeToCustomMatchDisplayPage(window fyne.Window, previousPage func(), nextPage func()){
currentPage := func(){setAddAttributeToCustomMatchDisplayPage(window, previousPage, nextPage)}
title := getPageTitleCentered("Add Attribute")
backButton := getBackButtonCentered(previousPage)
description := getLabelCentered("Choose the attribute to display.")
getPageContent := func()(*fyne.Container, error){
getCustomDisplayAttributesList := func()([]string, error){
exists, currentAttributesListString, err := mySettings.GetSetting("CustomMatchDisplayAttributesList")
if (err != nil) { return nil, err }
if (exists == false){
emptyList := make([]string, 0)
return emptyList, nil
}
currentAttributesList := strings.Split(currentAttributesListString, ",")
return currentAttributesList, nil
}
customDisplayAttributesList, err := getCustomDisplayAttributesList()
if (err != nil){ return nil, err }
if (len(customDisplayAttributesList) >= 5){
return nil, errors.New("setAddAttributeToCustomMatchDisplayPage called when attributesList is full.")
}
generalAttributeButtonsGrid := container.NewGridWithColumns(1)
physicalAttributeButtonsGrid := container.NewGridWithColumns(1)
lifestyleAttributeButtonsGrid := container.NewGridWithColumns(1)
mentalAttributeButtonsGrid := container.NewGridWithColumns(1)
addAttributeButton := func(attributeName string, attributeType string)error{
isSelected := slices.Contains(customDisplayAttributesList, attributeName)
if (isSelected == true){
// Attribute has already been selected
// We will not show it
return nil
}
attributeTitle, _, _, _, _, err := attributeDisplay.GetProfileAttributeDisplayInfo(attributeName)
if (err != nil) { return err }
attributeButton := widget.NewButton(attributeTitle, func(){
newAttributesList := append(customDisplayAttributesList, attributeName)
newAttributesListString := strings.Join(newAttributesList, ",")
err := mySettings.SetSetting("CustomMatchDisplayAttributesList", newAttributesListString)
if (err != nil) {
setErrorEncounteredPage(window, err, currentPage)
return
}
nextPage()
})
if (attributeType == "General"){
generalAttributeButtonsGrid.Add(attributeButton)
} else if (attributeType == "Physical"){
physicalAttributeButtonsGrid.Add(attributeButton)
} else if (attributeType == "Lifestyle"){
lifestyleAttributeButtonsGrid.Add(attributeButton)
} else if (attributeType == "Mental"){
mentalAttributeButtonsGrid.Add(attributeButton)
} else {
return errors.New("addAttributeButton called with invalid attributeType: " + attributeType)
}
return nil
}
generalAttributeNamesList := []string{
"MatchScore",
"Username",
"Sexuality",
"Distance",
"HasMessagedMe",
"IHaveMessaged",
"HasRejectedMe",
"IsLiked",
"IsMyContact",
"SearchTermsCount",
"PrimaryLocationCountry",
}
physicalAttributeNamesList := []string{
"Age",
"Height",
"Sex",
"HairColor",
"HairTexture",
"EyeColor",
"SkinColor",
"RacialSimilarity",
"HasHIV",
"HasGenitalHerpes",
"BodyFat",
"BodyMuscle",
"23andMe_MaternalHaplogroup",
"23andMe_PaternalHaplogroup",
"23andMe_NeanderthalVariants",
"EyeColorSimilarity",
"EyeColorGenesSimilarity",
"HairColorSimilarity",
"HairColorGenesSimilarity",
"SkinColorSimilarity",
"SkinColorGenesSimilarity",
"HairTextureSimilarity",
"HairTextureGenesSimilarity",
"FacialStructureGenesSimilarity",
"23andMe_AncestralSimilarity",
"23andMe_MaternalHaplogroupSimilarity",
"23andMe_PaternalHaplogroupSimilarity",
"OffspringProbabilityOfAnyMonogenicDisease",
"TotalPolygenicDiseaseRiskScore",
"OffspringTotalPolygenicDiseaseRiskScore",
"AutismRiskScore",
"OffspringAutismRiskScore",
"ObesityRiskScore",
"OffspringObesityRiskScore",
"PredictedEyeColor",
"OffspringBlueEyesProbability",
"OffspringGreenEyesProbability",
"OffspringHazelEyesProbability",
"OffspringBrownEyesProbability",
"PredictedLactoseTolerance",
"OffspringLactoseToleranceProbability",
"PredictedHairTexture",
"OffspringStraightHairProbability",
"OffspringCurlyHairProbability",
"HomosexualnessScore",
"OffspringHomosexualnessScore",
"PredictedHeight",
"OffspringPredictedHeight",
}
lifestyleAttributeNamesList := []string{
"Fame",
"WealthInGold",
"AlcoholFrequency",
"TobaccoFrequency",
"CannabisFrequency",
"FruitRating",
"VegetablesRating",
"NutsRating",
"GrainsRating",
"DairyRating",
"SeafoodRating",
"BeefRating",
"PorkRating",
"PoultryRating",
"EggsRating",
"BeansRating",
}
mentalAttributeNamesList := []string{
"GenderIdentity",
"PetsRating",
"DogsRating",
"CatsRating",
}
for _, attributeName := range generalAttributeNamesList{
err = addAttributeButton(attributeName, "General")
if (err != nil) { return nil, err }
}
for _, attributeName := range physicalAttributeNamesList{
err = addAttributeButton(attributeName, "Physical")
if (err != nil) { return nil, err }
}
for _, attributeName := range lifestyleAttributeNamesList{
err = addAttributeButton(attributeName, "Lifestyle")
if (err != nil) { return nil, err }
}
for _, attributeName := range mentalAttributeNamesList{
err = addAttributeButton(attributeName, "Mental")
if (err != nil) { return nil, err }
}
generalLabel := getBoldLabelCentered("General")
physicalLabel := getBoldLabelCentered("Physical")
lifestyleLabel := getBoldLabelCentered("Lifestyle")
mentalLabel := getBoldLabelCentered("Mental")
generalAttributeButtonsGridCentered := getContainerCentered(generalAttributeButtonsGrid)
physicalAttributeButtonsGridCentered := getContainerCentered(physicalAttributeButtonsGrid)
lifestyleAttributeButtonsGridCentered := getContainerCentered(lifestyleAttributeButtonsGrid)
mentalAttributeButtonsGridCentered := getContainerCentered(mentalAttributeButtonsGrid)
pageContent := container.NewVBox(generalLabel, widget.NewSeparator(), generalAttributeButtonsGridCentered, widget.NewSeparator(), physicalLabel, widget.NewSeparator(), physicalAttributeButtonsGridCentered, widget.NewSeparator(), lifestyleLabel, widget.NewSeparator(), lifestyleAttributeButtonsGridCentered, widget.NewSeparator(), mentalLabel, widget.NewSeparator(), mentalAttributeButtonsGridCentered)
return pageContent, nil
}
pageContent, err := getPageContent()
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
page := container.NewVBox(title, backButton, widget.NewSeparator(), description, widget.NewSeparator(), pageContent)
setPageContent(page, window)
}
func setConfigureMatchScorePage(window fyne.Window, previousPage func()){
setLoadingScreen(window, "Configure Match Score", "Loading Configure Match Score page...")
currentPage := func(){setConfigureMatchScorePage(window, previousPage)}
title := getPageTitleCentered("Configure Match Score")
backButton := getBackButtonCentered(previousPage)
description1 := getLabelCentered("Customize how a user's match score is calculated.")
description2 := getLabelCentered("Each desire's points will be added to a user's match score if they fulfills the desire.")
description3 := getLabelCentered("Increase the Point value for desires that are more important to you.")
viewMatchScoreDistributionButton := getWidgetCentered(widget.NewButtonWithIcon("View Match Score Distribution", theme.VisibilityIcon(), func(){
setViewUserAttributeStatisticsPage_BarChart(window, "Mate", "MatchScore", "Number Of Users", " users", true, false, false, nil, false, nil, nil, currentPage)
}))
//TODO: Split into multiple pages and add Navigation buttons
getDesirePointsGrid := func()(*fyne.Container, error){
desireNameLabel := getItalicLabelCentered("Desire Name")
pointsLabel := getItalicLabelCentered("Points")
emptyLabel := widget.NewLabel("")
desireTitleColumn := container.NewVBox(desireNameLabel, widget.NewSeparator())
desirePointsColumn := container.NewVBox(pointsLabel, widget.NewSeparator())
editPointsButtonsColumn := container.NewVBox(emptyLabel, widget.NewSeparator())
allMyDesiresList := myMateDesires.GetAllMyDesiresList(false)
for _, desireName := range allMyDesiresList{
desireTitle, err := mateDesires.GetDesireTitleFromDesireName(desireName)
if (err != nil) { return nil, err }
desireTitleTranslated := translate(desireTitle)
desireTitleLabel := getBoldLabelCentered(desireTitleTranslated)
desirePoints, err := myMatchScore.GetMyMatchScoreDesirePoints(desireName)
if (err != nil) { return nil, err }
desirePointsString := helpers.ConvertIntToString(desirePoints)
desirePointsLabel := getBoldLabelCentered(desirePointsString)
editPointsButton := widget.NewButtonWithIcon("", theme.DocumentCreateIcon(), func(){
setEditMatchScoreDesirePointsPage(window, desireName, currentPage)
})
desireTitleColumn.Add(desireTitleLabel)
desirePointsColumn.Add(desirePointsLabel)
editPointsButtonsColumn.Add(editPointsButton)
desireTitleColumn.Add(widget.NewSeparator())
desirePointsColumn.Add(widget.NewSeparator())
editPointsButtonsColumn.Add(widget.NewSeparator())
}
desirePointsGrid := container.NewHBox(layout.NewSpacer(), desireTitleColumn, desirePointsColumn, editPointsButtonsColumn, layout.NewSpacer())
return desirePointsGrid, nil
}
desirePointsGrid, err := getDesirePointsGrid()
if (err != nil) {
setErrorEncounteredPage(window, err, previousPage)
return
}
page := container.NewVBox(title, backButton, widget.NewSeparator(), description1, description2, description3, widget.NewSeparator(), viewMatchScoreDistributionButton, widget.NewSeparator(), desirePointsGrid)
setPageContent(page, window)
}
func setEditMatchScoreDesirePointsPage(window fyne.Window, desireName string, previousPage func()){
currentPage := func(){setEditMatchScoreDesirePointsPage(window, desireName, previousPage)}
title := getPageTitleCentered("Edit Attribute Points")
backButton := getBackButtonCentered(previousPage)
description1 := getLabelCentered("Edit your desire's points.")
description2 := getLabelCentered("These will be added to a user's match score if they fulfill the desire.")
desireTitle, err := mateDesires.GetDesireTitleFromDesireName(desireName)
if (err != nil) {
setErrorEncounteredPage(window, err, previousPage)
return
}
desireNameLabel := widget.NewLabel("Desire Name:")
desireTitleLabel := getBoldLabel(desireTitle)
desireTitleRow := container.NewHBox(layout.NewSpacer(), desireNameLabel, desireTitleLabel, layout.NewSpacer())
desirePoints, err := myMatchScore.GetMyMatchScoreDesirePoints(desireName)
if (err != nil) {
setErrorEncounteredPage(window, err, previousPage)
return
}
desirePointsString := helpers.ConvertIntToString(desirePoints)
desirePointsTitle := getBoldLabelCentered("Desire Points:")
desirePointsLabel := getBoldLabelCentered(desirePointsString)
getDecreasePointsButton := func()fyne.Widget{
if (desirePoints > 1){
decreaseButton := widget.NewButton("-", func(){
err := myMatchScore.SetMyMatchScoreDesirePoints(desireName, desirePoints-1)
if (err != nil) {
setErrorEncounteredPage(window, err, currentPage)
return
}
currentPage()
})
return decreaseButton
}
emptyButton := widget.NewButton("", nil)
return emptyButton
}
getIncreasePointsButton := func()fyne.Widget{
if (desirePoints < 100){
increaseButton := widget.NewButton("+", func(){
err := myMatchScore.SetMyMatchScoreDesirePoints(desireName, desirePoints+1)
if (err != nil) {
setErrorEncounteredPage(window, err, currentPage)
return
}
currentPage()
})
return increaseButton
}
emptyButton := widget.NewButton("", nil)
return emptyButton
}
decreasePointsButton := getDecreasePointsButton()
increasePointsButton := getIncreasePointsButton()
decreaseIncreaseButtons := getContainerCentered(container.NewGridWithColumns(2, decreasePointsButton, increasePointsButton))
page := container.NewVBox(title, backButton, widget.NewSeparator(), description1, description2, widget.NewSeparator(), desireTitleRow, widget.NewSeparator(), desirePointsTitle, desirePointsLabel, decreaseIncreaseButtons)
setPageContent(page, window)
}
// This page will explain a user's match score by describing which desires the user passes
func setViewUserMatchScoreBreakdownPage(window fyne.Window, userIdentityHash [16]byte, previousPage func()){
userIdentityType, err := identity.GetIdentityTypeFromIdentityHash(userIdentityHash)
if (err != nil){
userIdentityHashHex := encoding.EncodeBytesToHexString(userIdentityHash[:])
setErrorEncounteredPage(window, errors.New("setViewUserMatchScoreBreakdownPage called with invalid userIdentityHash: " + userIdentityHashHex), previousPage)
return
}
if (userIdentityType != "Mate"){
setErrorEncounteredPage(window, errors.New("setViewUserMatchScoreBreakdownPage called with non-mate identity hash."), previousPage)
return
}
currentPage := func(){setViewUserMatchScoreBreakdownPage(window, userIdentityHash, previousPage)}
title := getPageTitleCentered("User Match Score Breakdown")
backButton := getBackButtonCentered(previousPage)
appNetworkType, err := getAppNetworkType.GetAppNetworkType()
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
profileExists, _, getAnyUserProfileAttributeFunction, err := viewableProfiles.GetRetrieveAnyNewestViewableUserProfileAttributeFunction(userIdentityHash, appNetworkType, true, false, true)
if (err != nil) {
setErrorEncounteredPage(window, err, previousPage)
return
}
if (profileExists == false) {
// Profile must have been deleted or it is not viewable
description1 := getBoldLabelCentered("User's profile is not found.")
description2 := getLabelCentered("Thus, the user's match score breakdown cannot be shown.")
description3 := getLabelCentered("Their profile was either banned or deleted.")
description4 := getLabelCentered("Deletion should only happen if the user is no longer a match.")
page := container.NewVBox(title, backButton, widget.NewSeparator(), description1, description2, description3, description4)
setPageContent(page, window)
return
}
exists, _, userIsDisabled, err := getAnyUserProfileAttributeFunction("Disabled")
if (err != nil) {
setErrorEncounteredPage(window, err, previousPage)
return
}
if (exists == true && userIsDisabled == "Yes"){
// User's newest viewable profile is disabled.
description1 := getBoldLabelCentered("User's profile is disabled.")
description2 := getLabelCentered("Thus, the user's match score breakdown cannot be shown.")
page := container.NewVBox(title, backButton, widget.NewSeparator(), description1, description2)
setPageContent(page, window)
return
}
// This bool will track if we have any desires at all
anyPreferenceExists := false
userMatchScore := 0
// This map stores the number of points we added for each desire
// Map Structure: Desire name -> Points we added
desirePointsMap := make(map[string]int)
// This is a list of desires which the user fulfills
fulfilledDesiresList := make([]string, 0)
// This is a list of desires which the user does not fulfill
unfulfilledDesiresList := make([]string, 0)
// This is a list of desires for which we do not know if the user fulfills our preference, not caused by them not responding
unknownStatusDesiresList := make([]string, 0)
// This is a list of desires for which the user has no response
noResponseExistsDesiresList := make([]string, 0)
// This is a list of desires which we have no preference for
noPreferenceExistsDesiresList := make([]string, 0)
allMyDesiresList := myMateDesires.GetAllMyDesiresList(false)
for _, desireName := range allMyDesiresList{
myDesireExists, statusIsKnown, userFulfillsDesire, err := myMateDesires.CheckIfMateProfileFulfillsMyDesire(desireName, getAnyUserProfileAttributeFunction)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
if (myDesireExists == false){
noPreferenceExistsDesiresList = append(noPreferenceExistsDesiresList, desireName)
continue
}
anyPreferenceExists = true
if (statusIsKnown == false){
noResponseIsPossible, _ := mateDesires.CheckIfDesireAllowsRequireResponse(desireName)
if (noResponseIsPossible == false){
// Whether or not the user responded does not effect the desire's status is known status
// An example is OffspringProbabilityOfAnyMonogenicDisease, which requires information from us *and* the user
unknownStatusDesiresList = append(unknownStatusDesiresList, desireName)
continue
}
noResponseExistsDesiresList = append(noResponseExistsDesiresList, desireName)
continue
}
if (userFulfillsDesire == false){
unfulfilledDesiresList = append(unfulfilledDesiresList, desireName)
continue
}
fulfilledDesiresList = append(fulfilledDesiresList, desireName)
pointsToAdd, err := myMatchScore.GetMyMatchScoreDesirePoints(desireName)
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
desirePointsMap[desireName] += pointsToAdd
userMatchScore += pointsToAdd
}
if (anyPreferenceExists == false){
description1 := getBoldLabelCentered("You have not added any desires.")
description2 := getLabelCentered("Thus, the match score for all users will be 0.")
description3 := getLabelCentered("Visit the Desires page to enter some desires.")
page := container.NewVBox(title, backButton, widget.NewSeparator(), description1, description2, description3)
setPageContent(page, window)
return
}
matchScoreTitle := widget.NewLabel("User Match Score:")
matchScoreString := helpers.ConvertIntToString(userMatchScore)
matchScoreLabel := getBoldLabel(matchScoreString)
matchScoreRow := container.NewHBox(layout.NewSpacer(), matchScoreTitle, matchScoreLabel, layout.NewSpacer())
getMatchScoreBreakdownGrid := func()(*fyne.Container, error){
desireNameHeader := getItalicLabelCentered("Desire Name")
userFulfillsDesireHeader := getItalicLabelCentered("User Fulfills Desire")
pointsAddedHeader := getItalicLabelCentered("Points Added")
desireNameColumn := container.NewVBox(desireNameHeader, widget.NewSeparator())
userFulfillsDesireColumn := container.NewVBox(userFulfillsDesireHeader, widget.NewSeparator())
pointsAddedColumn := container.NewVBox(pointsAddedHeader, widget.NewSeparator())
for _, desireName := range fulfilledDesiresList{
desireTitle, err := mateDesires.GetDesireTitleFromDesireName(desireName)
if (err != nil) { return nil, err }
desireTitleLabel := getBoldLabelCentered(desireTitle)
userFulfillsDesireLabel := getBoldLabelCentered(translate("Yes"))
pointsAdded, exists := desirePointsMap[desireName]
if (exists == false){
return nil, errors.New("desirePointsMap missing desire: " + desireName)
}
pointsAddedString := helpers.ConvertIntToString(pointsAdded)
pointsAddedLabel := getBoldLabelCentered("+" + pointsAddedString)
desireNameColumn.Add(desireTitleLabel)
userFulfillsDesireColumn.Add(userFulfillsDesireLabel)
pointsAddedColumn.Add(pointsAddedLabel)
desireNameColumn.Add(widget.NewSeparator())
userFulfillsDesireColumn.Add(widget.NewSeparator())
pointsAddedColumn.Add(widget.NewSeparator())
}
for _, desireName := range unfulfilledDesiresList{
desireTitle, err := mateDesires.GetDesireTitleFromDesireName(desireName)
if (err != nil) { return nil, err }
desireTitleLabel := getBoldLabelCentered(desireTitle)
userFulfillsDesireLabel := getBoldLabelCentered(translate("No"))
pointsAddedLabel := getBoldLabelCentered("0")
desireNameColumn.Add(desireTitleLabel)
userFulfillsDesireColumn.Add(userFulfillsDesireLabel)
pointsAddedColumn.Add(pointsAddedLabel)
desireNameColumn.Add(widget.NewSeparator())
userFulfillsDesireColumn.Add(widget.NewSeparator())
pointsAddedColumn.Add(widget.NewSeparator())
}
for _, desireName := range unknownStatusDesiresList{
desireTitle, err := mateDesires.GetDesireTitleFromDesireName(desireName)
if (err != nil) { return nil, err }
desireTitleLabel := getBoldLabelCentered(desireTitle)
userFulfillsDesireLabel := getItalicLabelCentered(translate("Unknown"))
pointsAddedLabel := getBoldLabelCentered("0")
desireNameColumn.Add(desireTitleLabel)
userFulfillsDesireColumn.Add(userFulfillsDesireLabel)
pointsAddedColumn.Add(pointsAddedLabel)
desireNameColumn.Add(widget.NewSeparator())
userFulfillsDesireColumn.Add(widget.NewSeparator())
pointsAddedColumn.Add(widget.NewSeparator())
}
for _, desireName := range noResponseExistsDesiresList{
desireTitle, err := mateDesires.GetDesireTitleFromDesireName(desireName)
if (err != nil) { return nil, err }
desireTitleLabel := getBoldLabelCentered(desireTitle)
userFulfillsDesireLabel := getItalicLabelCentered(translate("No Response"))
pointsAddedLabel := getBoldLabelCentered("0")
desireNameColumn.Add(desireTitleLabel)
userFulfillsDesireColumn.Add(userFulfillsDesireLabel)
pointsAddedColumn.Add(pointsAddedLabel)
desireNameColumn.Add(widget.NewSeparator())
userFulfillsDesireColumn.Add(widget.NewSeparator())
pointsAddedColumn.Add(widget.NewSeparator())
}
matchScoreBreakdownGrid := container.NewHBox(layout.NewSpacer(), desireNameColumn, userFulfillsDesireColumn, pointsAddedColumn, layout.NewSpacer())
return matchScoreBreakdownGrid, nil
}
matchScoreBreakdownGrid, err := getMatchScoreBreakdownGrid()
if (err != nil){
setErrorEncounteredPage(window, err, previousPage)
return
}
page := container.NewVBox(title, backButton, widget.NewSeparator(), matchScoreRow, widget.NewSeparator(), matchScoreBreakdownGrid)
numberOfNoPreferenceDesires := len(noPreferenceExistsDesiresList)
if (numberOfNoPreferenceDesires != 0){
numberOfNoPreferenceDesiresString := helpers.ConvertIntToString(numberOfNoPreferenceDesires)
description1 := getLabelCentered("You have " + numberOfNoPreferenceDesiresString + " desires with no preference.")
description2 := getLabelCentered("These desires will have no impact on match scores.")
viewMyNoPreferenceDesiresButton := getWidgetCentered(widget.NewButtonWithIcon("View My No Preference Desires", theme.VisibilityIcon(), func(){
setViewMyNoPreferenceDesiresPage(window, noPreferenceExistsDesiresList, currentPage)
}))
page.Add(widget.NewSeparator())
page.Add(description1)
page.Add(description2)
page.Add(viewMyNoPreferenceDesiresButton)
}
setPageContent(page, window)
}
func setViewMyNoPreferenceDesiresPage(window fyne.Window, myNoPreferenceDesiresList []string, previousPage func()){
title := getPageTitleCentered("My No Preference Desires")
backButton := getBackButtonCentered(previousPage)
description := getLabelCentered("Below is a list of your desires for which you have no provided no preference.")
page := container.NewVBox(title, backButton, widget.NewSeparator(), description, widget.NewSeparator())
for _, desireName := range myNoPreferenceDesiresList{
desireTitle, err := mateDesires.GetDesireTitleFromDesireName(desireName)
if (err != nil) {
setErrorEncounteredPage(window, err, previousPage)
return
}
desireTitleLabel := getBoldLabelCentered(desireTitle)
page.Add(desireTitleLabel)
}
setPageContent(page, window)
}