2024-04-11 15:51:56 +02:00
package gui
//desiresGui_General.go implements pages to view and manage a user's General mate desires, view all their desires, and manage their download desires
import "fyne.io/fyne/v2"
import "fyne.io/fyne/v2/container"
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/resources/worldLanguages"
import "seekia/resources/worldLocations"
import "seekia/internal/allowedText"
import "seekia/internal/appMemory"
import "seekia/internal/desires/mateDesires"
import "seekia/internal/desires/myLocalDesires"
import "seekia/internal/encoding"
import "seekia/internal/globalSettings"
import "seekia/internal/helpers"
import "seekia/internal/network/myMateCriteria"
import "seekia/internal/profiles/attributeDisplay"
import "strings"
import "errors"
import "slices"
func setDesiresPage ( window fyne . Window ) {
appMemory . SetMemoryEntry ( "CurrentViewedPage" , "Desires" )
currentPage := func ( ) { setDesiresPage ( window ) }
title := getPageTitleCentered ( translate ( "My Mate Desires" ) )
description1 := getLabelCentered ( translate ( "Select your Mate desires." ) )
description2 := getLabelCentered ( translate ( "Your desires are used to generate your matches." ) )
description3 := getLabelCentered ( translate ( "These desires not shared on your profile." ) )
generalIcon , err := getFyneImageIcon ( "General" )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , func ( ) { setHomePage ( window ) } )
return
}
generalButton := widget . NewButton ( translate ( "General" ) , func ( ) {
setChooseDesiresCategoryPage_General ( window , currentPage )
} )
generalButtonWithIcon := container . NewGridWithRows ( 2 , generalIcon , generalButton )
physicalIcon , err := getFyneImageIcon ( "Person" )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , func ( ) { setHomePage ( window ) } )
return
}
physicalButton := widget . NewButton ( translate ( "Physical" ) , func ( ) {
setChooseDesiresCategoryPage_Physical ( window , currentPage )
} )
physicalButtonWithIcon := container . NewGridWithRows ( 2 , physicalIcon , physicalButton )
lifestyleIcon , err := getFyneImageIcon ( "Lifestyle" )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , func ( ) { setHomePage ( window ) } )
return
}
lifestyleButton := widget . NewButton ( translate ( "Lifestyle" ) , func ( ) {
setChooseDesiresCategoryPage_Lifestyle ( window , currentPage )
} )
lifestyleButtonWithIcon := container . NewGridWithRows ( 2 , lifestyleIcon , lifestyleButton )
mentalIcon , err := getFyneImageIcon ( "Mental" )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , func ( ) { setHomePage ( window ) } )
return
}
mentalButton := widget . NewButton ( translate ( "Mental" ) , func ( ) {
setChooseDesiresCategoryPage_Mental ( window , currentPage )
} )
mentalButtonWithIcon := container . NewGridWithRows ( 2 , mentalIcon , mentalButton )
categoriesRow := getContainerCentered ( container . NewGridWithRows ( 1 , generalButtonWithIcon , physicalButtonWithIcon , lifestyleButtonWithIcon , mentalButtonWithIcon ) )
allDesiresIcon , err := getFyneImageIcon ( "Choice" )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , func ( ) { setHomePage ( window ) } )
return
}
viewAllDesiresButton := widget . NewButton ( "View All Desires" , func ( ) {
setViewAllMyDesiresPage ( window , currentPage )
} )
viewAllDesiresButtonWithIcon := container . NewGridWithRows ( 2 , allDesiresIcon , viewAllDesiresButton )
statisticsIcon , err := getFyneImageIcon ( "Stats" )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , func ( ) { setHomePage ( window ) } )
return
}
viewAllStatisticsButton := widget . NewButton ( "View All Statistics" , func ( ) {
setViewAllMyDesireStatisticsPage ( window , false , 0 , 0 , nil , currentPage )
} )
viewAllStatisticsButtonWithIcon := container . NewGridWithColumns ( 1 , statisticsIcon , viewAllStatisticsButton )
viewAllButtonsRow := getContainerCentered ( container . NewGridWithRows ( 1 , viewAllDesiresButtonWithIcon , viewAllStatisticsButtonWithIcon ) )
downloadDesiresIcon , err := getFyneImageIcon ( "Host" )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , func ( ) { setHomePage ( window ) } )
return
}
downloadDesiresButton := widget . NewButton ( "Download Desires" , func ( ) {
setManageMateDownloadDesiresPage ( window , currentPage )
} )
downloadDesiresButtonWithIcon := getContainerCentered ( container . NewGridWithRows ( 2 , downloadDesiresIcon , downloadDesiresButton ) )
page := container . NewVBox ( title , widget . NewSeparator ( ) , description1 , description2 , description3 , widget . NewSeparator ( ) , categoriesRow , widget . NewSeparator ( ) , viewAllButtonsRow , widget . NewSeparator ( ) , downloadDesiresButtonWithIcon )
setPageContent ( page , window )
}
func setChooseDesiresCategoryPage_General ( window fyne . Window , previousPage func ( ) ) {
currentPage := func ( ) { setChooseDesiresCategoryPage_General ( window , previousPage ) }
title := getPageTitleCentered ( translate ( "My Mate Desires - General" ) )
backButton := getBackButtonCentered ( previousPage )
profileLanguageButton := widget . NewButton ( "Profile Language" , func ( ) {
setChooseDesiresPage_ProfileLanguage ( window , currentPage )
} )
distanceButton := widget . NewButton ( "Distance" , func ( ) {
setChooseDesiresPage_Distance ( window , currentPage )
} )
countryButton := widget . NewButton ( "Country" , func ( ) {
setChooseDesiresPage_Country ( window , currentPage )
} )
sexualityButton := widget . NewButton ( "Sexuality" , func ( ) {
setChooseDesiresPage_Sexuality ( window , currentPage )
} )
searchTermsButton := widget . NewButton ( "Search Terms" , func ( ) {
setChooseDesiresPage_SearchTerms ( window , currentPage )
} )
chatButton := widget . NewButton ( "Chat" , func ( ) {
setChooseDesiresPage_Chat ( window , currentPage )
} )
likedUsersButton := widget . NewButton ( "Liked Users" , func ( ) {
setChooseDesiresPage_LikedUsers ( window , currentPage )
} )
ignoredUsersButton := widget . NewButton ( "Ignored Users" , func ( ) {
setChooseDesiresPage_IgnoredUsers ( window , currentPage )
} )
contactsButton := widget . NewButton ( "Contacts" , func ( ) {
setChooseDesiresPage_Contacts ( window , currentPage )
} )
buttonsGrid := getContainerCentered ( container . NewGridWithColumns ( 1 , profileLanguageButton , distanceButton , countryButton , sexualityButton , searchTermsButton , chatButton , likedUsersButton , ignoredUsersButton , contactsButton ) )
buttonsGridPadded := container . NewPadded ( buttonsGrid )
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , buttonsGridPadded )
setPageContent ( page , window )
}
func setChooseDesiresPage_ProfileLanguage ( window fyne . Window , previousPage func ( ) ) {
currentPage := func ( ) { setChooseDesiresPage_ProfileLanguage ( window , previousPage ) }
title := getPageTitleCentered ( "My Mate Desires - General" )
backButton := getBackButtonCentered ( previousPage )
subtitle := getPageSubtitleCentered ( "Profile Language" )
description1 := getLabelCentered ( "Choose your profile language desires." )
description2 := getLabelCentered ( "A profile language is the language that a profile is written in." )
description3 := getLabelCentered ( "Choose all of the languages you can read." )
getSelectedLanguagesSection := func ( ) ( * fyne . Container , error ) {
getCurrentDesiredChoicesList := func ( ) ( [ ] string , error ) {
currentChoicesListExists , currentChoicesList , err := myLocalDesires . GetDesire ( "ProfileLanguage" )
if ( err != nil ) { return nil , err }
if ( currentChoicesListExists == false ) {
emptyList := make ( [ ] string , 0 )
return emptyList , nil
}
//currentChoicesList is a "+" separated list of choices
// Each choice option is encoded in base64
currentDesiredChoicesList := strings . Split ( currentChoicesList , "+" )
return currentDesiredChoicesList , nil
}
currentDesiredChoicesList , err := getCurrentDesiredChoicesList ( )
if ( err != nil ) { return nil , err }
addLanguageButton := getWidgetCentered ( widget . NewButtonWithIcon ( "Add Language" , theme . ContentAddIcon ( ) , func ( ) {
submitLanguageFunction := func ( newLanguageIdentifier int , _ string ) error {
newLanguageIdentifierString := helpers . ConvertIntToString ( newLanguageIdentifier )
newLanguageIdentifierBase64 := encoding . EncodeBytesToBase64String ( [ ] byte ( newLanguageIdentifierString ) )
newLanguagesList := helpers . AddItemToStringListAndAvoidDuplicate ( currentDesiredChoicesList , newLanguageIdentifierBase64 )
newDesireString := strings . Join ( newLanguagesList , "+" )
err = myLocalDesires . SetDesire ( "ProfileLanguage" , newDesireString )
if ( err != nil ) { return err }
return nil
}
setChooseDesiresPage_AddLanguage ( window , submitLanguageFunction , currentPage , currentPage )
} ) )
if ( len ( currentDesiredChoicesList ) == 0 ) {
noLanguagesLabel := getBoldLabelCentered ( "No Languages Selected." )
selectedLanguagesSection := container . NewVBox ( noLanguagesLabel , addLanguageButton )
return selectedLanguagesSection , nil
}
myDesiredLanguagesLabel := getItalicLabelCentered ( "My Desired Languages:" )
languageNameColumn := container . NewVBox ( widget . NewSeparator ( ) )
deleteButtonsColumn := container . NewVBox ( widget . NewSeparator ( ) )
for _ , languageIdentifierBase64 := range currentDesiredChoicesList {
languageIdentifierString , err := encoding . DecodeBase64StringToUnicodeString ( languageIdentifierBase64 )
if ( err != nil ) {
return nil , errors . New ( "My current profile language desire is malformed: Contains invalid language: " + languageIdentifierBase64 )
}
languageIdentifier , err := helpers . ConvertStringToInt ( languageIdentifierString )
if ( err != nil ) {
return nil , errors . New ( "My current profile language desire is malformed: Contains invalid language: " + languageIdentifierString )
}
languageObject , err := worldLanguages . GetLanguageObjectFromLanguageIdentifier ( languageIdentifier )
if ( err != nil ) {
return nil , errors . New ( "My current profile language desire is malformed: Contains unknown language identifier: " + languageIdentifierString )
}
languageNamesList := languageObject . NamesList
languageDescription := helpers . TranslateAndJoinStringListItems ( languageNamesList , "/" )
languageDescriptionTrimmed , _ , err := helpers . TrimAndFlattenString ( languageDescription , 20 )
if ( err != nil ) { return nil , err }
languageNameLabel := getBoldLabelCentered ( languageDescriptionTrimmed )
deleteLanguageButton := widget . NewButtonWithIcon ( "" , theme . DeleteIcon ( ) , func ( ) {
2024-08-11 14:31:40 +02:00
newDesiredLanguagesList , _ := helpers . DeleteAllMatchingItemsFromList ( currentDesiredChoicesList , languageIdentifierBase64 )
2024-04-11 15:51:56 +02:00
if ( len ( newDesiredLanguagesList ) == 0 ) {
err := myLocalDesires . DeleteDesire ( "ProfileLanguage" )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , currentPage )
return
}
currentPage ( )
return
}
newDesireValueString := strings . Join ( newDesiredLanguagesList , "+" )
err := myLocalDesires . SetDesire ( "ProfileLanguage" , newDesireValueString )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , currentPage )
return
}
currentPage ( )
} )
languageNameColumn . Add ( languageNameLabel )
deleteButtonsColumn . Add ( deleteLanguageButton )
languageNameColumn . Add ( widget . NewSeparator ( ) )
deleteButtonsColumn . Add ( widget . NewSeparator ( ) )
}
languagesGrid := container . NewHBox ( layout . NewSpacer ( ) , languageNameColumn , deleteButtonsColumn , layout . NewSpacer ( ) )
selectedLanguagesSection := container . NewVBox ( addLanguageButton , widget . NewSeparator ( ) , myDesiredLanguagesLabel , languagesGrid )
return selectedLanguagesSection , nil
}
selectedLanguagesSection , err := getSelectedLanguagesSection ( )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
filterOptionsSection , err := getDesireEditorFilterOptionsSection ( window , currentPage , "ProfileLanguage" , true )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
viewStatisticsButton := getWidgetCentered ( widget . NewButtonWithIcon ( "View Statistics" , theme . InfoIcon ( ) , func ( ) {
setViewMyMateDesireStatisticsPage ( window , "Profile Language" , "ProfileLanguage" , true , "Bar" , "ProfileLanguage" , currentPage )
} ) )
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , subtitle , widget . NewSeparator ( ) , description1 , description2 , description3 , widget . NewSeparator ( ) , selectedLanguagesSection , widget . NewSeparator ( ) , filterOptionsSection , widget . NewSeparator ( ) , viewStatisticsButton )
setPageContent ( page , window )
}
func setChooseDesiresPage_Distance ( window fyne . Window , previousPage func ( ) ) {
currentPage := func ( ) { setChooseDesiresPage_Distance ( window , previousPage ) }
title := getPageTitleCentered ( translate ( "My Mate Desires - General" ) )
backButton := getBackButtonCentered ( previousPage )
subtitle := getPageSubtitleCentered ( translate ( "Distance" ) )
description1 := getLabelCentered ( "Choose your desired user distance." )
description2 := getLabelCentered ( "You must add a primary location to your profile to calculate distance." )
metricOrImperialSwitchButton , err := getMetricImperialSwitchButton ( window , currentPage )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
currentUnitsLabel := getItalicLabel ( "Current Units:" )
currentUnitsRow := container . NewHBox ( layout . NewSpacer ( ) , currentUnitsLabel , metricOrImperialSwitchButton , layout . NewSpacer ( ) )
getMyMetricOrImperial := func ( ) ( string , error ) {
exists , metricOrImperial , err := globalSettings . GetSetting ( "MetricOrImperial" )
if ( err != nil ) { return "" , err }
if ( exists == false ) {
return "Metric" , nil
}
if ( metricOrImperial != "Metric" && metricOrImperial != "Imperial" ) {
return "" , errors . New ( "Malformed globalSettings: Invalid metricOrImperial: " + metricOrImperial )
}
return metricOrImperial , nil
}
myMetricOrImperial , err := getMyMetricOrImperial ( )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
getCurrentUnits := func ( ) string {
if ( myMetricOrImperial == "Metric" ) {
return "kilometers"
}
return "miles"
}
currentUnits := getCurrentUnits ( )
// Distance is normally represented in metric
// Metric is the standard, and Imperial is custom
getUnitsAreCustomBool := func ( ) bool {
if ( myMetricOrImperial == "Metric" ) {
return false
}
return true
}
unitsAreCustomBool := getUnitsAreCustomBool ( )
convertToMetricFunction := helpers . ConvertMilesToKilometers
convertToImperialFunction := helpers . ConvertKilometersToMiles
desireEditor , err := getDesireEditor_Numeric ( window , currentPage , "Distance" , 0 , 20000 , currentUnits , 2 , unitsAreCustomBool , convertToMetricFunction , convertToImperialFunction , false , "" , "" , nil )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
viewStatisticsButton := getWidgetCentered ( widget . NewButtonWithIcon ( "View Statistics" , theme . InfoIcon ( ) , func ( ) {
setViewMyMateDesireStatisticsPage ( window , "Distance" , "Distance" , true , "Bar" , "Distance" , currentPage )
} ) )
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , subtitle , widget . NewSeparator ( ) , description1 , description2 , widget . NewSeparator ( ) , currentUnitsRow , widget . NewSeparator ( ) , desireEditor , widget . NewSeparator ( ) , viewStatisticsButton )
setPageContent ( page , window )
}
func setChooseDesiresPage_Country ( window fyne . Window , previousPage func ( ) ) {
currentPage := func ( ) { setChooseDesiresPage_Country ( window , previousPage ) }
title := getPageTitleCentered ( "My Mate Desires - General" )
backButton := getBackButtonCentered ( previousPage )
subtitle := getPageSubtitleCentered ( "Country" )
description1 := getLabelCentered ( "Choose your country desires." )
description2 := getLabelCentered ( "Select the countries where you want your matches to live in." )
description3 := getLabelCentered ( "Most users should only use this desire if they live near a border." )
description4 := getLabelCentered ( "Most users should only need to use the Distance desire." )
getSelectedCountriesSection := func ( ) ( * fyne . Container , error ) {
getCurrentDesiredChoicesList := func ( ) ( [ ] string , error ) {
currentChoicesListExists , currentChoicesList , err := myLocalDesires . GetDesire ( "PrimaryLocationCountry" )
if ( err != nil ) { return nil , err }
if ( currentChoicesListExists == false ) {
emptyList := make ( [ ] string , 0 )
return emptyList , nil
}
//currentChoicesList is a "+" separated list of choices
// Each choice option is encoded in base64
currentDesiredChoicesList := strings . Split ( currentChoicesList , "+" )
return currentDesiredChoicesList , nil
}
currentDesiredChoicesList , err := getCurrentDesiredChoicesList ( )
if ( err != nil ) { return nil , err }
addCountryButton := getWidgetCentered ( widget . NewButtonWithIcon ( "Add Country" , theme . ContentAddIcon ( ) , func ( ) {
setChooseMateDesiresPage_ChooseCountry ( window , currentPage , currentPage )
} ) )
if ( len ( currentDesiredChoicesList ) == 0 ) {
noCountriesLabel := getBoldLabelCentered ( "No Countries Selected." )
selectedCountriesSection := container . NewVBox ( noCountriesLabel , addCountryButton )
return selectedCountriesSection , nil
}
myDesiredCountriesLabel := getItalicLabelCentered ( "My Desired Countries:" )
countryNameColumn := container . NewVBox ( widget . NewSeparator ( ) )
deleteButtonsColumn := container . NewVBox ( widget . NewSeparator ( ) )
for _ , countryIdentifierBase64 := range currentDesiredChoicesList {
countryIdentifierString , err := encoding . DecodeBase64StringToUnicodeString ( countryIdentifierBase64 )
if ( err != nil ) {
return nil , errors . New ( "My current profile country desire is malformed: Contains invalid country: " + countryIdentifierBase64 )
}
countryIdentifier , err := helpers . ConvertStringToInt ( countryIdentifierString )
if ( err != nil ) {
return nil , errors . New ( "My current profile country desire is malformed: Contains invalid country: " + countryIdentifierString )
}
countryObject , err := worldLocations . GetCountryObjectFromCountryIdentifier ( countryIdentifier )
if ( err != nil ) {
return nil , errors . New ( "My current profile country is malformed: Contains unknown country identifier: " + countryIdentifierString )
}
countryNamesList := countryObject . NamesList
countryDescription := helpers . TranslateAndJoinStringListItems ( countryNamesList , "/" )
countryNameLabel := getBoldLabelCentered ( countryDescription )
deleteCountryButton := widget . NewButtonWithIcon ( "" , theme . DeleteIcon ( ) , func ( ) {
2024-08-11 14:31:40 +02:00
newDesiredCountriesList , _ := helpers . DeleteAllMatchingItemsFromList ( currentDesiredChoicesList , countryIdentifierBase64 )
2024-04-11 15:51:56 +02:00
if ( len ( newDesiredCountriesList ) == 0 ) {
err := myLocalDesires . DeleteDesire ( "PrimaryLocationCountry" )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , currentPage )
return
}
currentPage ( )
return
}
newDesireValueString := strings . Join ( newDesiredCountriesList , "+" )
err := myLocalDesires . SetDesire ( "PrimaryLocationCountry" , newDesireValueString )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , currentPage )
return
}
currentPage ( )
} )
countryNameColumn . Add ( countryNameLabel )
deleteButtonsColumn . Add ( deleteCountryButton )
countryNameColumn . Add ( widget . NewSeparator ( ) )
deleteButtonsColumn . Add ( widget . NewSeparator ( ) )
}
countriesGrid := container . NewHBox ( layout . NewSpacer ( ) , countryNameColumn , deleteButtonsColumn , layout . NewSpacer ( ) )
selectedCountriesSection := container . NewVBox ( addCountryButton , widget . NewSeparator ( ) , myDesiredCountriesLabel , countriesGrid )
return selectedCountriesSection , nil
}
selectedCountriesSection , err := getSelectedCountriesSection ( )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
filterOptionsSection , err := getDesireEditorFilterOptionsSection ( window , currentPage , "PrimaryLocationCountry" , true )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
viewStatisticsButton := getWidgetCentered ( widget . NewButtonWithIcon ( "View Statistics" , theme . InfoIcon ( ) , func ( ) {
setViewMyMateDesireStatisticsPage ( window , "Country" , "PrimaryLocationCountry" , true , "Donut" , "PrimaryLocationCountry" , currentPage )
} ) )
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , subtitle , widget . NewSeparator ( ) , description1 , description2 , description3 , description4 , widget . NewSeparator ( ) , selectedCountriesSection , widget . NewSeparator ( ) , filterOptionsSection , widget . NewSeparator ( ) , viewStatisticsButton )
setPageContent ( page , window )
}
func setChooseMateDesiresPage_ChooseCountry ( window fyne . Window , previousPage func ( ) , nextPage func ( ) ) {
currentPage := func ( ) { setChooseMateDesiresPage_ChooseCountry ( window , previousPage , nextPage ) }
title := getPageTitleCentered ( translate ( "My Mate Desires - General" ) )
backButton := getBackButtonCentered ( previousPage )
subtitle := getPageSubtitleCentered ( translate ( "Add Country" ) )
description1 := getLabelCentered ( "Choose the country to add." )
allCountryObjectsList , err := worldLocations . GetAllCountryObjectsList ( )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
allTranslatedCountriesList := make ( [ ] string , 0 , len ( allCountryObjectsList ) )
// Map Structure: Country Description -> Country identifier
countryIdentifiersMap := make ( map [ string ] int )
for _ , countryObject := range allCountryObjectsList {
countryIdentifier := countryObject . Identifier
countryNamesList := countryObject . NamesList
countryDescription := helpers . TranslateAndJoinStringListItems ( countryNamesList , "/" )
countryIdentifiersMap [ countryDescription ] = countryIdentifier
allTranslatedCountriesList = append ( allTranslatedCountriesList , countryDescription )
}
helpers . SortStringListToUnicodeOrder ( allTranslatedCountriesList )
onSelectedFunction := func ( selectedCountryIndex int ) {
selectedCountryDescription := allTranslatedCountriesList [ selectedCountryIndex ]
selectedCountryIdentifier , exists := countryIdentifiersMap [ selectedCountryDescription ]
if ( exists == false ) {
setErrorEncounteredPage ( window , errors . New ( "countryIdentifiersMap missing country description." ) , currentPage )
return
}
selectedCountryIdentifierString := helpers . ConvertIntToString ( selectedCountryIdentifier )
newCountryIdentifierBase64 := encoding . EncodeBytesToBase64String ( [ ] byte ( selectedCountryIdentifierString ) )
getNewDesiredAttributeList := func ( ) ( [ ] string , error ) {
currentChoicesListExists , currentChoicesList , err := myLocalDesires . GetDesire ( "PrimaryLocationCountry" )
if ( err != nil ) { return nil , err }
if ( currentChoicesListExists == false ) {
newList := [ ] string { newCountryIdentifierBase64 }
return newList , nil
}
//currentChoicesList is a "+" separated list of choices
// Each choice option is encoded in base64
currentDesiredChoicesList := strings . Split ( currentChoicesList , "+" )
newCountriesList := helpers . AddItemToStringListAndAvoidDuplicate ( currentDesiredChoicesList , newCountryIdentifierBase64 )
return newCountriesList , nil
}
newDesiredAttributeList , err := getNewDesiredAttributeList ( )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , currentPage )
return
}
newDesireString := strings . Join ( newDesiredAttributeList , "+" )
err = myLocalDesires . SetDesire ( "PrimaryLocationCountry" , newDesireString )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , currentPage )
return
}
nextPage ( )
}
widgetList , err := getFyneWidgetListFromStringList ( allTranslatedCountriesList , onSelectedFunction )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
header := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , subtitle , widget . NewSeparator ( ) , description1 , widget . NewSeparator ( ) )
page := container . NewBorder ( header , nil , nil , nil , widgetList )
setPageContent ( page , window )
}
func setChooseDesiresPage_Sexuality ( window fyne . Window , previousPage func ( ) ) {
currentPage := func ( ) { setChooseDesiresPage_Sexuality ( window , previousPage ) }
title := getPageTitleCentered ( "My Mate Desires - General" )
backButton := getBackButtonCentered ( previousPage )
subtitle := getPageSubtitleCentered ( translate ( "Sexuality" ) )
description1 := getLabelCentered ( "Choose the user sexualities that you desire." )
description2 := getLabelCentered ( "This refers to which sexes the users are interested in." )
description3 := getLabelCentered ( "For example, if you are Male, you should at least select Male." )
option1Translated := translate ( "Male" )
option2Translated := translate ( "Female" )
option3Translated := translate ( "Male And Female" )
optionTitlesList := [ ] string { option1Translated , option2Translated , option3Translated }
optionNamesMap := map [ string ] [ ] string {
option1Translated : [ ] string { "Male" } ,
option2Translated : [ ] string { "Female" } ,
option3Translated : [ ] string { "Male And Female" } ,
}
desireEditor , err := getDesireEditor_Choice ( window , currentPage , "Sexuality" , optionTitlesList , optionNamesMap , false , true , 1 )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
viewStatisticsButton := getWidgetCentered ( widget . NewButtonWithIcon ( "View Statistics" , theme . InfoIcon ( ) , func ( ) {
setViewMyMateDesireStatisticsPage ( window , "Sexuality" , "Sexuality" , true , "Donut" , "Sexuality" , currentPage )
} ) )
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , subtitle , widget . NewSeparator ( ) , description1 , description2 , description3 , widget . NewSeparator ( ) , desireEditor , widget . NewSeparator ( ) , viewStatisticsButton )
setPageContent ( page , window )
}
func setChooseDesiresPage_SearchTerms ( window fyne . Window , previousPage func ( ) ) {
currentPage := func ( ) { setChooseDesiresPage_SearchTerms ( window , previousPage ) }
title := getPageTitleCentered ( translate ( "My Mate Desires - General" ) )
backButton := getBackButtonCentered ( previousPage )
subtitle := getPageSubtitleCentered ( "Search Terms" )
description1 := getLabelCentered ( "Choose your desired search terms." )
description2 := getLabelCentered ( "Seekia will search through each user's profile for your terms." )
description3 := getLabelCentered ( "Each user's description, tags, hobbies, and beliefs will be searched." )
description4 := getLabelCentered ( "A user's profile must contain at least 1 of your terms to pass the desire." )
getSelectedSearchTermsSection := func ( ) ( * fyne . Container , error ) {
getCurrentDesiredChoicesList := func ( ) ( [ ] string , error ) {
currentChoicesListExists , currentChoicesList , err := myLocalDesires . GetDesire ( "SearchTerms" )
if ( err != nil ) { return nil , err }
if ( currentChoicesListExists == false ) {
emptyList := make ( [ ] string , 0 )
return emptyList , nil
}
// currentChoicesList is a "+" separated list of choices
// Each choice option is encoded in base64
currentDesiredChoicesList := strings . Split ( currentChoicesList , "+" )
return currentDesiredChoicesList , nil
}
currentDesiredChoicesList , err := getCurrentDesiredChoicesList ( )
if ( err != nil ) { return nil , err }
addTermEntry := widget . NewEntry ( )
addTermEntry . SetPlaceHolder ( "Enter term name..." )
addTermButton := getWidgetCentered ( widget . NewButtonWithIcon ( "Add Term" , theme . ContentAddIcon ( ) , func ( ) {
newTermName := addTermEntry . Text
if ( newTermName == "" ) {
return
}
isAllowed := allowedText . VerifyStringIsAllowed ( newTermName )
if ( isAllowed == false ) {
title := translate ( "Invalid Term Name" )
dialogMessageA := getLabelCentered ( translate ( "Your search term contains an invalid character." ) )
dialogMessageB := getLabelCentered ( translate ( "It must be encoded in UTF-8." ) )
dialogMessageC := getLabelCentered ( translate ( "Remove this character and resubmit." ) )
dialogContent := container . NewVBox ( dialogMessageA , dialogMessageB , dialogMessageC )
dialog . ShowCustom ( title , translate ( "Close" ) , dialogContent , window )
return
}
containsTabsOrNewlines := helpers . CheckIfStringContainsTabsOrNewlines ( newTermName )
if ( containsTabsOrNewlines == true ) {
title := translate ( "Invalid Term Name" )
dialogMessageA := getLabelCentered ( translate ( "Your search term contains a tab or a newline." ) )
dialogMessageB := getLabelCentered ( translate ( "Remove the tab or newline and resubmit." ) )
dialogContent := container . NewVBox ( dialogMessageA , dialogMessageB )
dialog . ShowCustom ( title , translate ( "Close" ) , dialogContent , window )
return
}
termNameBase64 := encoding . EncodeBytesToBase64String ( [ ] byte ( newTermName ) )
newDesireList := helpers . AddItemToStringListAndAvoidDuplicate ( currentDesiredChoicesList , termNameBase64 )
newDesireAttributeValue := strings . Join ( newDesireList , "+" )
err := myLocalDesires . SetDesire ( "SearchTerms" , newDesireAttributeValue )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , currentPage )
return
}
currentPage ( )
} ) )
addTermRow := getContainerCentered ( container . NewGridWithRows ( 1 , addTermEntry , addTermButton ) )
if ( len ( currentDesiredChoicesList ) == 0 ) {
noTermsExistLabel := getBoldLabelCentered ( "No Terms Exist." )
selectedSearchTermsSection := container . NewVBox ( addTermRow , widget . NewSeparator ( ) , noTermsExistLabel )
return selectedSearchTermsSection , nil
}
myDesiredTermsLabel := getItalicLabelCentered ( "My Desired Terms:" )
termNameColumn := container . NewVBox ( widget . NewSeparator ( ) )
deleteButtonsColumn := container . NewVBox ( widget . NewSeparator ( ) )
for _ , termNameBase64 := range currentDesiredChoicesList {
termName , err := encoding . DecodeBase64StringToUnicodeString ( termNameBase64 )
if ( err != nil ) {
return nil , errors . New ( "My current search terms desire is malformed: Contains invalid term: " + termNameBase64 )
}
termNameLabel := getBoldLabelCentered ( termName )
deleteTermButton := widget . NewButtonWithIcon ( "" , theme . DeleteIcon ( ) , func ( ) {
2024-08-11 14:31:40 +02:00
newDesiredTermsList , _ := helpers . DeleteAllMatchingItemsFromList ( currentDesiredChoicesList , termNameBase64 )
2024-04-11 15:51:56 +02:00
if ( len ( newDesiredTermsList ) == 0 ) {
err := myLocalDesires . DeleteDesire ( "SearchTerms" )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , currentPage )
return
}
currentPage ( )
return
}
newDesireValueString := strings . Join ( newDesiredTermsList , "+" )
err := myLocalDesires . SetDesire ( "SearchTerms" , newDesireValueString )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , currentPage )
return
}
currentPage ( )
} )
termNameColumn . Add ( termNameLabel )
deleteButtonsColumn . Add ( deleteTermButton )
termNameColumn . Add ( widget . NewSeparator ( ) )
deleteButtonsColumn . Add ( widget . NewSeparator ( ) )
}
termsGrid := container . NewHBox ( layout . NewSpacer ( ) , termNameColumn , deleteButtonsColumn , layout . NewSpacer ( ) )
selectedTermsSection := container . NewVBox ( addTermRow , widget . NewSeparator ( ) , myDesiredTermsLabel , termsGrid )
return selectedTermsSection , nil
}
selectedTermsSection , err := getSelectedSearchTermsSection ( )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
filterOptionsSection , err := getDesireEditorFilterOptionsSection ( window , currentPage , "SearchTerms" , false )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
viewStatisticsButton := getWidgetCentered ( widget . NewButtonWithIcon ( "View Statistics" , theme . InfoIcon ( ) , func ( ) {
setViewMyMateDesireStatisticsPage ( window , "Search Terms" , "SearchTerms" , true , "Bar" , "SearchTermsCount" , currentPage )
} ) )
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , subtitle , widget . NewSeparator ( ) , description1 , description2 , description3 , description4 , widget . NewSeparator ( ) , selectedTermsSection , widget . NewSeparator ( ) , filterOptionsSection , widget . NewSeparator ( ) , viewStatisticsButton )
setPageContent ( page , window )
}
func setChooseDesiresPage_Chat ( window fyne . Window , previousPage func ( ) ) {
currentPage := func ( ) { setChooseDesiresPage_Chat ( window , previousPage ) }
title := getPageTitleCentered ( translate ( "My Mate Desires - General" ) )
backButton := getBackButtonCentered ( previousPage )
subtitle := getPageSubtitleCentered ( "Chat Desires" )
description1 := getLabelCentered ( "Choose your chat desires." )
hasMessagedMeButton := widget . NewButton ( "Has Messaged Me" , func ( ) {
setChooseDesiresPage_HasMessagedMe ( window , currentPage )
} )
iHaveMessagedButton := widget . NewButton ( "I Have Messaged" , func ( ) {
setChooseDesiresPage_IHaveMessaged ( window , currentPage )
} )
hasRejectedMeButton := widget . NewButton ( "Has Rejected Me" , func ( ) {
setChooseDesiresPage_HasRejectedMe ( window , currentPage )
} )
hasAnsweredQuestionnaireButton := widget . NewButton ( "Has Answered Questionnaire" , func ( ) {
//TODO
// We need to include the functionality to only show users who responded in a specified way
// For example, if the user's question is: Do you like french fries?, and the user has 2 options: Yes/No,
// the user should be able to filter users who answered with yes/no
showUnderConstructionDialog ( window )
} )
buttonsGrid := getContainerCentered ( container . NewGridWithColumns ( 1 , hasMessagedMeButton , iHaveMessagedButton , hasRejectedMeButton , hasAnsweredQuestionnaireButton ) )
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , subtitle , widget . NewSeparator ( ) , description1 , widget . NewSeparator ( ) , buttonsGrid )
setPageContent ( page , window )
}
func setChooseDesiresPage_HasMessagedMe ( window fyne . Window , previousPage func ( ) ) {
currentPage := func ( ) { setChooseDesiresPage_HasMessagedMe ( window , previousPage ) }
title := getPageTitleCentered ( "My Mate Desires - General" )
backButton := getBackButtonCentered ( previousPage )
subtitle := getPageSubtitleCentered ( "Has Messaged Me" )
description1 := getLabelCentered ( "Use this desire to show or hide users who have messaged you." )
description2 := getLabelCentered ( "Select the kind of users to include in your matches." )
//TODO: Change this to HasGreetedMe? Currently, a user who has rejected us will be included by this desire
option1Translated := translate ( "Has Messaged Me" )
option2Translated := translate ( "Has Not Messaged Me" )
optionTitlesList := [ ] string { option1Translated , option2Translated }
optionNamesMap := map [ string ] [ ] string {
option1Translated : [ ] string { "Yes" } ,
option2Translated : [ ] string { "No" } ,
}
desireEditor , err := getDesireEditor_Choice ( window , currentPage , "HasMessagedMe" , optionTitlesList , optionNamesMap , false , false , 1 )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
viewStatisticsButton := getWidgetCentered ( widget . NewButtonWithIcon ( "View Statistics" , theme . InfoIcon ( ) , func ( ) {
setViewMyMateDesireStatisticsPage ( window , "Has Messaged Me" , "HasMessagedMe" , true , "Donut" , "HasMessagedMe" , currentPage )
} ) )
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , subtitle , widget . NewSeparator ( ) , description1 , description2 , widget . NewSeparator ( ) , desireEditor , widget . NewSeparator ( ) , viewStatisticsButton )
setPageContent ( page , window )
}
func setChooseDesiresPage_IHaveMessaged ( window fyne . Window , previousPage func ( ) ) {
currentPage := func ( ) { setChooseDesiresPage_IHaveMessaged ( window , previousPage ) }
title := getPageTitleCentered ( "My Mate Desires - General" )
backButton := getBackButtonCentered ( previousPage )
subtitle := getPageSubtitleCentered ( "I Have Messaged" )
description1 := getLabelCentered ( "Use this desire to show or hide users whom you have messaged." )
description2 := getLabelCentered ( "Select the kind of users to include in your matches." )
option1Translated := translate ( "I Have Messaged" )
option2Translated := translate ( "I Have Not Messaged" )
optionTitlesList := [ ] string { option1Translated , option2Translated }
optionNamesMap := map [ string ] [ ] string {
option1Translated : [ ] string { "Yes" } ,
option2Translated : [ ] string { "No" } ,
}
desireEditor , err := getDesireEditor_Choice ( window , currentPage , "IHaveMessaged" , optionTitlesList , optionNamesMap , false , false , 1 )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
viewStatisticsButton := getWidgetCentered ( widget . NewButtonWithIcon ( "View Statistics" , theme . InfoIcon ( ) , func ( ) {
setViewMyMateDesireStatisticsPage ( window , "I Have Messaged" , "IHaveMessaged" , true , "Donut" , "IHaveMessaged" , currentPage )
} ) )
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , subtitle , widget . NewSeparator ( ) , description1 , description2 , widget . NewSeparator ( ) , desireEditor , widget . NewSeparator ( ) , viewStatisticsButton )
setPageContent ( page , window )
}
func setChooseDesiresPage_HasRejectedMe ( window fyne . Window , previousPage func ( ) ) {
currentPage := func ( ) { setChooseDesiresPage_HasRejectedMe ( window , previousPage ) }
title := getPageTitleCentered ( translate ( "My Mate Desires - General" ) )
backButton := getBackButtonCentered ( previousPage )
subtitle := getPageSubtitleCentered ( "Has Rejected Me" )
description1 := getLabelCentered ( "Use this desire to show or hide users who have rejected you." )
description2 := getLabelCentered ( "These are users who sent you a message that they are not interested." )
description3 := getLabelCentered ( "Select the kind of users to include in your matches." )
option1Translated := translate ( "Has Rejected Me" )
option2Translated := translate ( "Has Not Rejected Me" )
optionTitlesList := [ ] string { option1Translated , option2Translated }
optionNamesMap := map [ string ] [ ] string {
option1Translated : [ ] string { "Yes" } ,
option2Translated : [ ] string { "No" } ,
}
desireEditor , err := getDesireEditor_Choice ( window , currentPage , "HasRejectedMe" , optionTitlesList , optionNamesMap , false , false , 1 )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
viewStatisticsButton := getWidgetCentered ( widget . NewButtonWithIcon ( "View Statistics" , theme . InfoIcon ( ) , func ( ) {
setViewMyMateDesireStatisticsPage ( window , "Has Rejected Me" , "HasRejectedMe" , true , "Donut" , "HasRejectedMe" , currentPage )
} ) )
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , subtitle , widget . NewSeparator ( ) , description1 , description2 , description3 , widget . NewSeparator ( ) , desireEditor , widget . NewSeparator ( ) , viewStatisticsButton )
setPageContent ( page , window )
}
func setChooseDesiresPage_LikedUsers ( window fyne . Window , previousPage func ( ) ) {
currentPage := func ( ) { setChooseDesiresPage_LikedUsers ( window , previousPage ) }
title := getPageTitleCentered ( translate ( "My Mate Desires - General" ) )
backButton := getBackButtonCentered ( previousPage )
subtitle := getPageSubtitleCentered ( "Liked Users" )
description1 := getLabelCentered ( "Use this desire to show or hide liked users." )
description2 := getLabelCentered ( "A liked user is a user that you have added to your likes." )
description3 := getLabelCentered ( "Select the kind of users to include in your matches." )
option1Translated := translate ( "Liked" )
option2Translated := translate ( "Not Liked" )
optionTitlesList := [ ] string { option1Translated , option2Translated }
optionNamesMap := map [ string ] [ ] string {
option1Translated : [ ] string { "Yes" } ,
option2Translated : [ ] string { "No" } ,
}
desireEditor , err := getDesireEditor_Choice ( window , currentPage , "IsLiked" , optionTitlesList , optionNamesMap , false , false , 1 )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
viewStatisticsButton := getWidgetCentered ( widget . NewButtonWithIcon ( "View Statistics" , theme . InfoIcon ( ) , func ( ) {
setViewMyMateDesireStatisticsPage ( window , "Is Liked" , "IsLiked" , true , "Donut" , "IsLiked" , currentPage )
} ) )
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , subtitle , widget . NewSeparator ( ) , description1 , description2 , description3 , widget . NewSeparator ( ) , desireEditor , widget . NewSeparator ( ) , viewStatisticsButton )
setPageContent ( page , window )
}
func setChooseDesiresPage_IgnoredUsers ( window fyne . Window , previousPage func ( ) ) {
currentPage := func ( ) { setChooseDesiresPage_IgnoredUsers ( window , previousPage ) }
title := getPageTitleCentered ( translate ( "My Mate Desires - General" ) )
backButton := getBackButtonCentered ( previousPage )
subtitle := getPageSubtitleCentered ( "Ignored Users" )
description1 := getLabelCentered ( "Use this desire to show or hide ignored users." )
description2 := getLabelCentered ( "An Ignored user is a user that you have ignored." )
description3 := getLabelCentered ( "Select the kind of users to include in your matches." )
option1Translated := translate ( "Ignored" )
option2Translated := translate ( "Not Ignored" )
optionTitlesList := [ ] string { option1Translated , option2Translated }
optionNamesMap := map [ string ] [ ] string {
option1Translated : [ ] string { "Yes" } ,
option2Translated : [ ] string { "No" } ,
}
desireEditor , err := getDesireEditor_Choice ( window , currentPage , "IsIgnored" , optionTitlesList , optionNamesMap , false , false , 1 )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
viewStatisticsButton := getWidgetCentered ( widget . NewButtonWithIcon ( "View Statistics" , theme . InfoIcon ( ) , func ( ) {
setViewMyMateDesireStatisticsPage ( window , "Is Ignored" , "IsIgnored" , true , "Donut" , "IsIgnored" , currentPage )
} ) )
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , subtitle , widget . NewSeparator ( ) , description1 , description2 , description3 , widget . NewSeparator ( ) , desireEditor , widget . NewSeparator ( ) , viewStatisticsButton )
setPageContent ( page , window )
}
func setChooseDesiresPage_Contacts ( window fyne . Window , previousPage func ( ) ) {
currentPage := func ( ) { setChooseDesiresPage_Contacts ( window , previousPage ) }
title := getPageTitleCentered ( translate ( "My Mate Desires - General" ) )
backButton := getBackButtonCentered ( previousPage )
subtitle := getPageSubtitleCentered ( "Contacts" )
description1 := getLabelCentered ( "Use this desire to show or hide your contacts." )
description2 := getLabelCentered ( "These are users you have added to your contacts." )
description3 := getLabelCentered ( "Select the kind of users to include in your matches." )
option1Translated := translate ( "Is My Contact" )
option2Translated := translate ( "Is Not My Contact" )
optionTitlesList := [ ] string { option1Translated , option2Translated }
optionNamesMap := map [ string ] [ ] string {
option1Translated : [ ] string { "Yes" } ,
option2Translated : [ ] string { "No" } ,
}
desireEditor , err := getDesireEditor_Choice ( window , currentPage , "IsMyContact" , optionTitlesList , optionNamesMap , false , false , 1 )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
viewStatisticsButton := getWidgetCentered ( widget . NewButtonWithIcon ( "View Statistics" , theme . InfoIcon ( ) , func ( ) {
setViewMyMateDesireStatisticsPage ( window , "Is My Contact" , "IsMyContact" , true , "Donut" , "IsMyContact" , currentPage )
} ) )
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , subtitle , widget . NewSeparator ( ) , description1 , description2 , description3 , widget . NewSeparator ( ) , desireEditor , widget . NewSeparator ( ) , viewStatisticsButton )
setPageContent ( page , window )
}
// This function provides the editor to edit a choice desire
// A choice desire is one where there are a some canonical choices available, and the potential for an "Other" choice
// Inputs:
// -fyne.Window
// -func(): Current page
// -string: Desire name
// -[]string: Option titles list: What each check will show. Example: "1/5", "2/5", "3/5", "4/5", "5/5")
// -map[string][]string: Option Title -> Option Names list (Example ("1/5" -> "1", "2/5" -> "2"...)
// -bool: Show other choice: True if we want to show the "Other" option
// -bool: Show the "Require Response" button (false for attributes which do not allow that option)
// -int: Number of columns for the grid
// Outputs:
// -*fyne.Container
// -error
func getDesireEditor_Choice ( window fyne . Window , currentPage func ( ) , desireName string , optionTitlesList [ ] string , optionsNamesMap map [ string ] [ ] string , showOtherChoice bool , showRequireResponseButton bool , numberOfGridColumns int ) ( * fyne . Container , error ) {
getCurrentDesiredChoicesList := func ( ) ( [ ] string , error ) {
currentChoicesListExists , currentChoicesList , err := myLocalDesires . GetDesire ( desireName )
if ( err != nil ) { return nil , err }
if ( currentChoicesListExists == false ) {
emptyList := make ( [ ] string , 0 )
return emptyList , nil
}
//currentChoicesList is a "+" separated list of choices
// Each choice option is encoded in base64 (Except for "Other")
currentDesiredChoicesList := strings . Split ( currentChoicesList , "+" )
return currentDesiredChoicesList , nil
}
currentDesiredChoicesList , err := getCurrentDesiredChoicesList ( )
if ( err != nil ) { return nil , err }
selectButtonsGrid := container . NewGridWithColumns ( numberOfGridColumns )
for _ , optionTitle := range optionTitlesList {
optionNamesList , exists := optionsNamesMap [ optionTitle ]
if ( exists == false ) {
return nil , errors . New ( "getDesireEditor_Choice called with optionsNamesMap missing optionTitle: " + optionTitle )
}
optionBase64NamesList := make ( [ ] string , 0 , len ( optionNamesList ) )
for _ , optionName := range optionNamesList {
optionNameBase64 := encoding . EncodeBytesToBase64String ( [ ] byte ( optionName ) )
optionBase64NamesList = append ( optionBase64NamesList , optionNameBase64 )
}
handleSelectFunction := func ( selection bool ) {
//Outputs:
// -[]string: New desire attribute list (list of base64 option names)
getNewDesireAttributeList := func ( ) [ ] string {
if ( selection == false ) {
if ( len ( currentDesiredChoicesList ) == 0 ) {
// This should not happen, because the option was already selected
// The list should have had at least 1 item before
emptyList := make ( [ ] string , 0 )
return emptyList
}
newAttributeList := make ( [ ] string , 0 )
for _ , optionNameBase64 := range currentDesiredChoicesList {
// We see if this option name belongs to the current optionTitle
// If it does, we remove it from our selected attributes list
shouldDelete := slices . Contains ( optionBase64NamesList , optionNameBase64 )
if ( shouldDelete == false ) {
newAttributeList = append ( newAttributeList , optionNameBase64 )
}
}
return newAttributeList
}
//selection == true
newDesiredChoicesList := slices . Concat ( currentDesiredChoicesList , optionBase64NamesList )
duplicatesRemovedList := helpers . RemoveDuplicatesFromStringList ( newDesiredChoicesList )
return duplicatesRemovedList
}
newDesireAttributeList := getNewDesireAttributeList ( )
if ( len ( newDesireAttributeList ) == 0 ) {
err := myLocalDesires . DeleteDesire ( desireName )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , currentPage )
return
}
currentPage ( )
return
}
newDesireAttribute := strings . Join ( newDesireAttributeList , "+" )
err := myLocalDesires . SetDesire ( desireName , newDesireAttribute )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , currentPage )
return
}
currentPage ( )
}
optionSelectCheck := widget . NewCheck ( optionTitle , handleSelectFunction )
getChoiceIsSelectedBool := func ( ) bool {
// Every option name associated with this choice must be selected for this choice to be considered selected
for _ , optionNameBase64 := range optionBase64NamesList {
listContainsItem := slices . Contains ( currentDesiredChoicesList , optionNameBase64 )
if ( listContainsItem == false ) {
return false
}
}
return true
}
choiceIsSelected := getChoiceIsSelectedBool ( )
if ( choiceIsSelected == true ) {
optionSelectCheck . Checked = true
}
selectButtonsGrid . Add ( optionSelectCheck )
}
if ( showOtherChoice == true ) {
handleOtherSelectFunction := func ( selection bool ) {
//Outputs:
// -[]string: New desire attribute list (list of base64 option names)
getNewDesireAttributeList := func ( ) [ ] string {
if ( selection == false ) {
if ( len ( currentDesiredChoicesList ) == 0 ) {
// This should not happen, because "Other" had to have been selected for it to be deselected
emptyList := make ( [ ] string , 0 )
return emptyList
}
2024-08-11 14:31:40 +02:00
newAttributeList , _ := helpers . DeleteAllMatchingItemsFromList ( currentDesiredChoicesList , "Other" )
2024-04-11 15:51:56 +02:00
return newAttributeList
}
//selection == true
newAttributeList := helpers . AddItemToStringListAndAvoidDuplicate ( currentDesiredChoicesList , "Other" )
return newAttributeList
}
newDesireAttributeList := getNewDesireAttributeList ( )
if ( len ( newDesireAttributeList ) == 0 ) {
err := myLocalDesires . DeleteDesire ( desireName )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , currentPage )
return
}
currentPage ( )
return
}
newDesireAttribute := strings . Join ( newDesireAttributeList , "+" )
err := myLocalDesires . SetDesire ( desireName , newDesireAttribute )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , currentPage )
return
}
currentPage ( )
}
otherSelectCheck := widget . NewCheck ( "Other" , handleOtherSelectFunction )
otherIsSelected := slices . Contains ( currentDesiredChoicesList , "Other" )
if ( otherIsSelected == true ) {
otherSelectCheck . Checked = true
}
selectButtonsGrid . Add ( otherSelectCheck )
}
selectButtonsGridCentered := getContainerCentered ( selectButtonsGrid )
filterOptionsSection , err := getDesireEditorFilterOptionsSection ( window , currentPage , desireName , showRequireResponseButton )
if ( err != nil ) { return nil , err }
desireEditor := container . NewVBox ( selectButtonsGridCentered , widget . NewSeparator ( ) , filterOptionsSection )
return desireEditor , nil
}
// This function provides the editor to edit a numeric attribute
// The user can choose a minimum and maximum allowed value
// Units are shown for each minimum/maximum value, and a secondary row of alternate units can optionally be shown
func getDesireEditor_Numeric (
window fyne . Window ,
currentPage func ( ) ,
desireName string ,
minimumAllowed int64 ,
maximumAllowed int64 ,
currentUnits string ,
unitsRoundingPrecision int ,
unitsAreCustom bool , // This will be true if we need to convert the shown units
convertToStandardFunction func ( float64 ) ( float64 , error ) ,
convertToCustomFunction func ( float64 ) ( float64 , error ) ,
showSecondaryForm bool , // Secondary form is an alternate representation of the bound. Example: Offspring variants
secondaryFormTitle string ,
secondaryFormPrefix string , // A prefix to add to the secondary form representation. Example: "~" for offspring variants
getSecondaryFormFunction func ( float64 ) ( float64 , error ) ) ( * fyne . Container , error ) {
getBoundColumn := func ( minimumOrMaximum string ) ( * fyne . Container , error ) {
if ( minimumOrMaximum != "Minimum" && minimumOrMaximum != "Maximum" ) {
return nil , errors . New ( "getBoundColumn called with invalid minimumOrMaximum: " + minimumOrMaximum )
}
desireBoundName := desireName + "_" + minimumOrMaximum
boundLabel := getBoldLabelCentered ( minimumOrMaximum )
myBoundExists , myCurrentBound , err := myLocalDesires . GetDesire ( desireBoundName )
if ( err != nil ) { return nil , err }
getMyBoundSection := func ( ) ( * fyne . Container , error ) {
if ( myBoundExists == false ) {
noneLabel := getBoldItalicLabelCentered ( translate ( "None" ) )
if ( showSecondaryForm == false ) {
return noneLabel , nil
}
noneLabel2 := getBoldItalicLabelCentered ( translate ( "None" ) )
secondaryFormTitle := getItalicLabelCentered ( secondaryFormTitle + ":" )
myBoundSection := container . NewVBox ( noneLabel , widget . NewSeparator ( ) , secondaryFormTitle , noneLabel2 )
return myBoundSection , nil
}
// This will convert the bound if unitsAreCustom is true
getMyCurrentBound := func ( ) ( float64 , error ) {
myBoundFloat64 , err := helpers . ConvertStringToFloat64 ( myCurrentBound )
if ( err != nil ) {
return 0 , errors . New ( "My " + desireName + " desire malformed: not float64: " + myCurrentBound )
}
if ( unitsAreCustom == false ) {
return myBoundFloat64 , nil
}
myBoundCustom , err := convertToCustomFunction ( myBoundFloat64 )
if ( err != nil ) {
return 0 , errors . New ( "My " + desireName + " desire malformed: is negative: " + myCurrentBound )
}
return myBoundCustom , nil
}
myCurrentBound , err := getMyCurrentBound ( )
if ( err != nil ) { return nil , err }
myCurrentBoundString := helpers . ConvertFloat64ToStringRounded ( myCurrentBound , unitsRoundingPrecision )
myBoundLabelText := myCurrentBoundString + " " + translate ( currentUnits )
myBoundLabel := getBoldLabelCentered ( myBoundLabelText )
if ( showSecondaryForm == false ) {
return myBoundLabel , nil
}
secondaryFormBound , err := getSecondaryFormFunction ( myCurrentBound )
if ( err != nil ) { return nil , err }
secondaryFormBoundString := helpers . ConvertFloat64ToStringRounded ( secondaryFormBound , unitsRoundingPrecision )
secondaryFormTitle := getItalicLabelCentered ( secondaryFormTitle + ":" )
mySecondaryFormBoundLabelText := secondaryFormPrefix + secondaryFormBoundString + " " + translate ( currentUnits )
mySecondaryFormBoundLabel := getBoldItalicLabelCentered ( mySecondaryFormBoundLabelText )
myBoundSection := container . NewVBox ( myBoundLabel , widget . NewSeparator ( ) , secondaryFormTitle , mySecondaryFormBoundLabel )
return myBoundSection , nil
}
myBoundSection , err := getMyBoundSection ( )
if ( err != nil ) { return nil , err }
minimumOrMaximumLowercase := strings . ToLower ( minimumOrMaximum )
boundEntry := widget . NewEntry ( )
if ( myBoundExists == true ) {
getMyCurrentBoundString := func ( ) ( string , error ) {
myCurrentBoundFloat64 , err := helpers . ConvertStringToFloat64 ( myCurrentBound )
if ( err != nil ) {
return "" , errors . New ( "My desires malformed: Contains invalid numeric desire: " + desireName )
}
if ( myCurrentBoundFloat64 < float64 ( minimumAllowed ) || myCurrentBoundFloat64 > float64 ( maximumAllowed ) ) {
return "" , errors . New ( "My desires malformed: Contains invalid numeric desire: " + desireName )
}
if ( unitsAreCustom == false ) {
myCurrentBoundRounded := helpers . ConvertFloat64ToStringRounded ( myCurrentBoundFloat64 , unitsRoundingPrecision )
return myCurrentBoundRounded , nil
}
myCurrentBoundCustom , err := convertToCustomFunction ( myCurrentBoundFloat64 )
if ( err != nil ) {
return "" , errors . New ( "My desires malformed: Contains invalid numeric desire: " + desireName )
}
myCurrentBoundCustomString := helpers . ConvertFloat64ToStringRounded ( myCurrentBoundCustom , unitsRoundingPrecision )
return myCurrentBoundCustomString , nil
}
myCurrentBoundString , err := getMyCurrentBoundString ( )
if ( err != nil ) { return nil , err }
boundEntry . SetText ( myCurrentBoundString )
} else {
boundEntry . SetPlaceHolder ( translate ( "Enter " + minimumOrMaximumLowercase + "..." ) )
}
saveBoundButton := widget . NewButtonWithIcon ( translate ( "Save" ) , theme . ConfirmIcon ( ) , func ( ) {
newBound := boundEntry . Text
if ( newBound == "" ) {
err := myLocalDesires . DeleteDesire ( desireBoundName )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , currentPage )
return
}
currentPage ( )
return
}
//TODO: If min is greater than max, or max is greater than min, show dialog and don't allow change
newBoundFloat64 , err := helpers . ConvertStringToFloat64 ( newBound )
if ( err != nil ) {
title := translate ( "Invalid Bound" )
dialogMessage := getLabelCentered ( translate ( "Your bound must be a number." ) )
dialogContent := container . NewVBox ( dialogMessage )
dialog . ShowCustom ( title , translate ( "Close" ) , dialogContent , window )
return
}
getNewDesireBoundConverted := func ( ) ( float64 , error ) {
if ( unitsAreCustom == false ) {
return newBoundFloat64 , nil
}
boundInStandardUnits , err := convertToStandardFunction ( newBoundFloat64 )
if ( err != nil ) {
return 0 , errors . New ( "Invalid new numeric bound: " + err . Error ( ) )
}
return boundInStandardUnits , nil
}
newDesireBoundConverted , err := getNewDesireBoundConverted ( )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , currentPage )
return
}
if ( newDesireBoundConverted < float64 ( minimumAllowed ) || newDesireBoundConverted > float64 ( maximumAllowed ) ) {
minimumAllowedString := helpers . ConvertInt64ToString ( minimumAllowed )
maximumAllowedString := helpers . ConvertInt64ToString ( maximumAllowed )
dialogTitle := translate ( "Invalid Desire" )
dialogMessage := getLabelCentered ( translate ( "Your " + minimumOrMaximumLowercase + " must be a number between " + minimumAllowedString + " and " + maximumAllowedString + "." ) )
dialogContent := container . NewVBox ( dialogMessage )
dialog . ShowCustom ( dialogTitle , translate ( "Close" ) , dialogContent , window )
return
}
newDesireBoundString := helpers . ConvertFloat64ToStringRounded ( newDesireBoundConverted , unitsRoundingPrecision )
err = myLocalDesires . SetDesire ( desireBoundName , newDesireBoundString )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , currentPage )
return
}
currentPage ( )
} )
saveBoundButtonWithEntry := container . NewGridWithRows ( 1 , boundEntry , saveBoundButton )
deleteBoundButton := widget . NewButtonWithIcon ( translate ( "No Preference" ) , theme . CancelIcon ( ) , func ( ) {
if ( myBoundExists == false ) {
return
}
err := myLocalDesires . DeleteDesire ( desireBoundName )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , currentPage )
return
}
currentPage ( )
} )
boundColumn := getContainerCentered ( container . NewVBox ( boundLabel , widget . NewSeparator ( ) , myBoundSection , widget . NewSeparator ( ) , saveBoundButtonWithEntry , deleteBoundButton ) )
return boundColumn , nil
}
minimumColumn , err := getBoundColumn ( "Minimum" )
if ( err != nil ) { return nil , err }
maximumColumn , err := getBoundColumn ( "Maximum" )
if ( err != nil ) { return nil , err }
boundColumns := getContainerCentered ( container . NewGridWithRows ( 1 , minimumColumn , maximumColumn ) )
filterOptionsSection , err := getDesireEditorFilterOptionsSection ( window , currentPage , desireName , true )
if ( err != nil ) { return nil , err }
editorContent := container . NewVBox ( boundColumns , widget . NewSeparator ( ) , filterOptionsSection )
return editorContent , nil
}
func getDesireEditorFilterOptionsSection ( window fyne . Window , currentPage func ( ) , desireName string , showRequireResponseButton bool ) ( * fyne . Container , error ) {
configureFiltersDescription := widget . NewLabel ( "Configure your desire filter options." )
desireFilterOptionsHelpButton := widget . NewButtonWithIcon ( "" , theme . QuestionIcon ( ) , func ( ) {
setDesireFilterOptionsExplainerPage ( window , currentPage )
} )
desireFilterOptionsDescriptionRow := container . NewHBox ( layout . NewSpacer ( ) , configureFiltersDescription , desireFilterOptionsHelpButton , layout . NewSpacer ( ) )
getFilterAllButton := func ( ) ( fyne . Widget , error ) {
filterAllExists , currentFilterAllResponse , err := myLocalDesires . GetDesire ( desireName + "_FilterAll" )
if ( err != nil ) { return nil , err }
if ( filterAllExists == true && currentFilterAllResponse == "Yes" ) {
button := widget . NewButtonWithIcon ( translate ( "Filter All" ) , theme . CheckButtonCheckedIcon ( ) , func ( ) {
_ = myLocalDesires . SetDesire ( desireName + "_FilterAll" , "No" )
currentPage ( )
} )
return button , nil
}
button := widget . NewButtonWithIcon ( translate ( "Filter All" ) , theme . CheckButtonIcon ( ) , func ( ) {
_ = myLocalDesires . SetDesire ( desireName + "_FilterAll" , "Yes" )
currentPage ( )
} )
return button , nil
}
filterAllButton , err := getFilterAllButton ( )
if ( err != nil ) { return nil , err }
if ( showRequireResponseButton == false ) {
filterAllButtonCentered := getWidgetCentered ( filterAllButton )
filterOptionsSection := container . NewVBox ( desireFilterOptionsDescriptionRow , filterAllButtonCentered )
return filterOptionsSection , nil
}
getRequireResponseButton := func ( ) ( fyne . Widget , error ) {
requireResponseExists , currentRequireResponse , err := myLocalDesires . GetDesire ( desireName + "_RequireResponse" )
if ( err != nil ) { return nil , err }
if ( requireResponseExists == true && currentRequireResponse == "Yes" ) {
button := widget . NewButtonWithIcon ( translate ( "Require Response" ) , theme . CheckButtonCheckedIcon ( ) , func ( ) {
_ = myLocalDesires . SetDesire ( desireName + "_RequireResponse" , "No" )
currentPage ( )
} )
return button , nil
}
button := widget . NewButtonWithIcon ( translate ( "Require Response" ) , theme . CheckButtonIcon ( ) , func ( ) {
_ = myLocalDesires . SetDesire ( desireName + "_RequireResponse" , "Yes" )
currentPage ( )
} )
return button , nil
}
requireResponseButton , err := getRequireResponseButton ( )
if ( err != nil ) { return nil , err }
filterSettingsButtonsGrid := getContainerCentered ( container . NewGridWithColumns ( 1 , filterAllButton , requireResponseButton ) )
filterOptionsSection := container . NewVBox ( desireFilterOptionsDescriptionRow , filterSettingsButtonsGrid )
return filterOptionsSection , nil
}
// This is a page to view all of a user's desires
func setViewAllMyDesiresPage ( window fyne . Window , previousPage func ( ) ) {
setLoadingScreen ( window , "My Mate Desires" , "Loading My Mate Desires..." )
appMemory . SetMemoryEntry ( "CurrentViewedPage" , "ViewAllMyDesires" )
currentPage := func ( ) { setViewAllMyDesiresPage ( window , previousPage ) }
title := getPageTitleCentered ( "My Mate Desires" )
backButton := getBackButtonCentered ( previousPage )
description := getLabelCentered ( "Below are all of your mate desires." )
getAllDesiresGrid := func ( ) ( * fyne . Container , error ) {
desireButtonsColumn := container . NewVBox ( widget . NewSeparator ( ) )
desireNameAndDataColumn := container . NewVBox ( widget . NewSeparator ( ) )
filterOptionChecksColumn := container . NewVBox ( widget . NewSeparator ( ) )
getFilterOptionCheck := func ( desireName string , optionType string ) ( fyne . Widget , error ) {
if ( optionType != "FilterAll" && optionType != "RequireResponse" ) {
return nil , errors . New ( "getFilterOptionCheck called with invalid optionType: " + optionType )
}
filterOptionDesireName := desireName + "_" + optionType
getOptionTitle := func ( ) string {
if ( optionType == "FilterAll" ) {
result := translate ( "Filter All" )
return result
}
result := translate ( "Require Response" )
return result
}
optionTitle := getOptionTitle ( )
filterOptionCheck := widget . NewCheck ( optionTitle , func ( newSelection bool ) {
newSelectionString := helpers . ConvertBoolToYesOrNoString ( newSelection )
_ = myLocalDesires . SetDesire ( filterOptionDesireName , newSelectionString )
} )
exists , currentValue , err := myLocalDesires . GetDesire ( filterOptionDesireName )
if ( err != nil ) { return nil , err }
if ( exists == true && currentValue == "Yes" ) {
filterOptionCheck . Checked = true
}
return filterOptionCheck , nil
}
addDesireRow_Numerical := func ( desireTitle string , desireName string , editPage func ( ) , barOrDonutChart string , attributeName string ) error {
editDesireButton := widget . NewButtonWithIcon ( "Edit" , theme . DocumentCreateIcon ( ) , editPage )
desireTitleLabel := getBoldLabelCentered ( desireTitle )
getDesireValueLabel := func ( ) ( * fyne . Container , error ) {
minimumExists , desireMinimum , err := myLocalDesires . GetDesire ( desireName + "_Minimum" )
if ( err != nil ) { return nil , err }
maximumExists , desireMaximum , err := myLocalDesires . GetDesire ( desireName + "_Maximum" )
if ( err != nil ) { return nil , err }
if ( minimumExists == false && maximumExists == false ) {
noPreferenceLabel := getItalicLabelCentered ( "No Preference" )
return noPreferenceLabel , nil
}
// We may have to format the desire value
// For example: converting distance units from kilometers to miles
_ , attributeIsNumerical , formatDesireValuesFunction , desireValueUnits , _ , err := attributeDisplay . GetProfileAttributeDisplayInfo ( attributeName )
if ( err != nil ) { return nil , err }
if ( attributeIsNumerical == false ) {
return nil , errors . New ( "addDesireRow_Numerical called with non-numerical attribute: " + attributeName )
}
getDesireRangeFormatted := func ( ) ( string , error ) {
if ( minimumExists == true && maximumExists == false ) {
desireMinimumFormatted , err := formatDesireValuesFunction ( desireMinimum )
if ( err != nil ) { return "" , err }
result := desireMinimumFormatted + "+"
return result , nil
}
if ( minimumExists == false && maximumExists == true ) {
desireMaximumFormatted , err := formatDesireValuesFunction ( desireMaximum )
if ( err != nil ) { return "" , err }
result := "<" + desireMaximumFormatted
return result , nil
}
desireMinimumFormatted , err := formatDesireValuesFunction ( desireMinimum )
if ( err != nil ) { return "" , err }
desireMaximumFormatted , err := formatDesireValuesFunction ( desireMaximum )
if ( err != nil ) { return "" , err }
result := desireMinimumFormatted + " - " + desireMaximumFormatted
return result , nil
}
desireRangeFormatted , err := getDesireRangeFormatted ( )
if ( err != nil ) { return nil , err }
labelText := desireRangeFormatted + desireValueUnits
minMaxLabel := getBoldItalicLabelCentered ( labelText )
return minMaxLabel , nil
}
desireValueLabel , err := getDesireValueLabel ( )
if ( err != nil ) { return err }
filterAllCheck , err := getFilterOptionCheck ( desireName , "FilterAll" )
if ( err != nil ) { return err }
requireResponseCheck , err := getFilterOptionCheck ( desireName , "RequireResponse" )
if ( err != nil ) { return err }
viewStatisticsButton := widget . NewButtonWithIcon ( "Stats" , theme . InfoIcon ( ) , func ( ) {
setViewMyMateDesireStatisticsPage ( window , desireTitle , desireName , true , barOrDonutChart , attributeName , currentPage )
} )
desireButtonsColumn . Add ( editDesireButton )
desireButtonsColumn . Add ( viewStatisticsButton )
desireNameAndDataColumn . Add ( desireTitleLabel )
desireNameAndDataColumn . Add ( desireValueLabel )
filterOptionChecksColumn . Add ( filterAllCheck )
filterOptionChecksColumn . Add ( requireResponseCheck )
desireButtonsColumn . Add ( widget . NewSeparator ( ) )
desireNameAndDataColumn . Add ( widget . NewSeparator ( ) )
filterOptionChecksColumn . Add ( widget . NewSeparator ( ) )
return nil
}
addDesireRow_Choice := func ( desireTitle string , desireName string , editPage func ( ) , barOrDonutChart string , attributeName string ) error {
editDesireButton := widget . NewButtonWithIcon ( "Edit" , theme . DocumentCreateIcon ( ) , editPage )
desireTitleLabel := getBoldLabelCentered ( desireTitle )
getChoiceValueLabel := func ( ) ( * fyne . Container , error ) {
desireExists , desireChoicesList , err := myLocalDesires . GetDesire ( desireName )
if ( err != nil ) { return nil , err }
if ( desireExists == false ) {
noPreferenceLabel := getItalicLabelCentered ( translate ( "No Preference" ) )
return noPreferenceLabel , nil
}
// We may have to format the desired choices for readability
// For example: Converting "1" -> "1/6"
_ , _ , formatDesireValuesFunction , desireValueUnits , _ , err := attributeDisplay . GetProfileAttributeDisplayInfo ( attributeName )
if ( err != nil ) { return nil , err }
getLabelText := func ( ) ( string , error ) {
base64ChoicesList := strings . Split ( desireChoicesList , "+" )
choicesList := make ( [ ] string , 0 , len ( base64ChoicesList ) )
for _ , base64Choice := range base64ChoicesList {
choiceString , err := encoding . DecodeBase64StringToUnicodeString ( base64Choice )
if ( err != nil ) {
return "" , errors . New ( "My Desire choices list is malformed: Contains non-base64 choice: " + base64Choice )
}
choiceFormatted , err := formatDesireValuesFunction ( choiceString )
if ( err != nil ) { return "" , err }
choiceFormattedWithUnits := choiceFormatted + desireValueUnits
choicesList = append ( choicesList , choiceFormattedWithUnits )
}
choicesListJoined := strings . Join ( choicesList , ", " )
choicesListTrimmed , _ , err := helpers . TrimAndFlattenString ( choicesListJoined , 35 )
if ( err != nil ) { return "" , err }
return choicesListTrimmed , nil
}
labelText , err := getLabelText ( )
if ( err != nil ) { return nil , err }
desireValueLabel := getBoldItalicLabelCentered ( labelText )
return desireValueLabel , nil
}
choiceValueLabel , err := getChoiceValueLabel ( )
if ( err != nil ) { return err }
filterAllCheck , err := getFilterOptionCheck ( desireName , "FilterAll" )
if ( err != nil ) { return err }
requireResponseCheck , err := getFilterOptionCheck ( desireName , "RequireResponse" )
if ( err != nil ) { return err }
viewStatisticsButton := widget . NewButtonWithIcon ( "Stats" , theme . InfoIcon ( ) , func ( ) {
setViewMyMateDesireStatisticsPage ( window , desireTitle , desireName , true , barOrDonutChart , attributeName , currentPage )
} )
desireButtonsColumn . Add ( editDesireButton )
desireButtonsColumn . Add ( viewStatisticsButton )
desireNameAndDataColumn . Add ( desireTitleLabel )
desireNameAndDataColumn . Add ( choiceValueLabel )
filterOptionChecksColumn . Add ( filterAllCheck )
filterOptionChecksColumn . Add ( requireResponseCheck )
desireButtonsColumn . Add ( widget . NewSeparator ( ) )
desireNameAndDataColumn . Add ( widget . NewSeparator ( ) )
filterOptionChecksColumn . Add ( widget . NewSeparator ( ) )
return nil
}
// This function is used for desires which are not choice/numerical, so their value cannot be displayed automatically
//TODO: Add a function to format the desire value to something readable
addDesireRow_Custom := func ( desireTitle string , desireName string , editPage func ( ) ) error {
editDesireButton := widget . NewButtonWithIcon ( "Edit" , theme . DocumentCreateIcon ( ) , editPage )
desireTitleLabel := getBoldLabelCentered ( desireTitle )
getDesireValueLabel := func ( ) ( * fyne . Container , error ) {
desireExists , _ , err := myLocalDesires . GetDesire ( desireName )
if ( err != nil ) { return nil , err }
if ( desireExists == false ) {
noPreferenceLabel := getItalicLabelCentered ( "No Preference" )
return noPreferenceLabel , nil
}
customLabel := getBoldItalicLabelCentered ( "Custom" )
return customLabel , nil
}
desireValueLabel , err := getDesireValueLabel ( )
if ( err != nil ) { return err }
filterAllCheck , err := getFilterOptionCheck ( desireName , "FilterAll" )
if ( err != nil ) { return err }
requireResponseCheck , err := getFilterOptionCheck ( desireName , "RequireResponse" )
if ( err != nil ) { return err }
desireButtonsColumn . Add ( editDesireButton )
desireButtonsColumn . Add ( widget . NewLabel ( "" ) )
desireNameAndDataColumn . Add ( desireTitleLabel )
desireNameAndDataColumn . Add ( desireValueLabel )
filterOptionChecksColumn . Add ( filterAllCheck )
filterOptionChecksColumn . Add ( requireResponseCheck )
desireButtonsColumn . Add ( widget . NewSeparator ( ) )
desireNameAndDataColumn . Add ( widget . NewSeparator ( ) )
filterOptionChecksColumn . Add ( widget . NewSeparator ( ) )
return nil
}
editAgeDesirePage := func ( ) { setChooseDesiresPage_Age ( window , currentPage ) }
err := addDesireRow_Numerical ( "Age" , "Age" , editAgeDesirePage , "Bar" , "Age" )
if ( err != nil ) { return nil , err }
editHeightDesirePage := func ( ) { setChooseDesiresPage_Height ( window , currentPage ) }
err = addDesireRow_Numerical ( "Height" , "Height" , editHeightDesirePage , "Bar" , "Height" )
if ( err != nil ) { return nil , err }
editWealthDesirePage := func ( ) { setChooseDesiresPage_Wealth ( window , currentPage ) }
err = addDesireRow_Numerical ( "Wealth" , "Wealth" , editWealthDesirePage , "Bar" , "WealthInGold" )
if ( err != nil ) { return nil , err }
editSexDesirePage := func ( ) { setChooseDesiresPage_Sex ( window , currentPage ) }
err = addDesireRow_Choice ( "Sex" , "Sex" , editSexDesirePage , "Donut" , "Sex" )
if ( err != nil ) { return nil , err }
editProfileLanguageDesirePage := func ( ) { setChooseDesiresPage_ProfileLanguage ( window , currentPage ) }
err = addDesireRow_Choice ( "Profile Language" , "ProfileLanguage" , editProfileLanguageDesirePage , "Bar" , "ProfileLanguage" )
if ( err != nil ) { return nil , err }
editCountryDesirePage := func ( ) { setChooseDesiresPage_Country ( window , currentPage ) }
err = addDesireRow_Choice ( "Country" , "PrimaryLocationCountry" , editCountryDesirePage , "Donut" , "PrimaryLocationCountry" )
if ( err != nil ) { return nil , err }
editSearchTermsDesirePage := func ( ) { setChooseDesiresPage_SearchTerms ( window , currentPage ) }
err = addDesireRow_Choice ( "Search Terms" , "SearchTerms" , editSearchTermsDesirePage , "Donut" , "SearchTermsCount" )
if ( err != nil ) { return nil , err }
editHasMessagedMeDesirePage := func ( ) { setChooseDesiresPage_HasMessagedMe ( window , currentPage ) }
err = addDesireRow_Choice ( "Has Messaged Me" , "HasMessagedMe" , editHasMessagedMeDesirePage , "Donut" , "HasMessagedMe" )
if ( err != nil ) { return nil , err }
editIHaveMessagedDesirePage := func ( ) { setChooseDesiresPage_IHaveMessaged ( window , currentPage ) }
err = addDesireRow_Choice ( "I Have Messaged" , "IHaveMessaged" , editIHaveMessagedDesirePage , "Donut" , "IHaveMessaged" )
if ( err != nil ) { return nil , err }
editHasRejectedMeDesirePage := func ( ) { setChooseDesiresPage_HasRejectedMe ( window , currentPage ) }
err = addDesireRow_Choice ( "Has Rejected Me" , "HasRejectedMe" , editHasRejectedMeDesirePage , "Donut" , "HasRejectedMe" )
if ( err != nil ) { return nil , err }
editIsLikedDesirePage := func ( ) { setChooseDesiresPage_LikedUsers ( window , currentPage ) }
err = addDesireRow_Choice ( "Is Liked" , "IsLiked" , editIsLikedDesirePage , "Donut" , "IsLiked" )
if ( err != nil ) { return nil , err }
editIsIgnoredDesirePage := func ( ) { setChooseDesiresPage_IgnoredUsers ( window , currentPage ) }
err = addDesireRow_Choice ( "Is Ignored" , "IsIgnored" , editIsIgnoredDesirePage , "Donut" , "IsIgnored" )
if ( err != nil ) { return nil , err }
editIsMyContactDesirePage := func ( ) { setChooseDesiresPage_Contacts ( window , currentPage ) }
err = addDesireRow_Choice ( "Is My Contact" , "IsMyContact" , editIsMyContactDesirePage , "Donut" , "IsMyContact" )
if ( err != nil ) { return nil , err }
editDistanceDesirePage := func ( ) { setChooseDesiresPage_Distance ( window , currentPage ) }
err = addDesireRow_Numerical ( "Distance" , "Distance" , editDistanceDesirePage , "Bar" , "Distance" )
if ( err != nil ) { return nil , err }
editSexualityDesirePage := func ( ) { setChooseDesiresPage_Sexuality ( window , currentPage ) }
err = addDesireRow_Choice ( "Sexuality" , "Sexuality" , editSexualityDesirePage , "Donut" , "Sexuality" )
if ( err != nil ) { return nil , err }
editBodyFatDesirePage := func ( ) { setChooseDesiresPage_BodyFat ( window , currentPage ) }
err = addDesireRow_Choice ( "Body Fat" , "BodyFat" , editBodyFatDesirePage , "Donut" , "BodyFat" )
if ( err != nil ) { return nil , err }
editBodyMuscleDesirePage := func ( ) { setChooseDesiresPage_BodyMuscle ( window , currentPage ) }
err = addDesireRow_Choice ( "Body Muscle" , "BodyMuscle" , editBodyMuscleDesirePage , "Donut" , "BodyMuscle" )
if ( err != nil ) { return nil , err }
editEyeColorDesirePage := func ( ) { setChooseDesiresPage_EyeColor ( window , currentPage ) }
err = addDesireRow_Choice ( "Eye Color" , "EyeColor" , editEyeColorDesirePage , "Donut" , "EyeColor" )
if ( err != nil ) { return nil , err }
editSkinColorDesirePage := func ( ) { setChooseDesiresPage_SkinColor ( window , currentPage ) }
err = addDesireRow_Choice ( "Skin Color" , "SkinColor" , editSkinColorDesirePage , "Donut" , "SkinColor" )
if ( err != nil ) { return nil , err }
editHairColorDesirePage := func ( ) { setChooseDesiresPage_HairColor ( window , currentPage ) }
err = addDesireRow_Choice ( "Hair Color" , "HairColor" , editHairColorDesirePage , "Donut" , "HairColor" )
if ( err != nil ) { return nil , err }
editHairTextureDesirePage := func ( ) { setChooseDesiresPage_HairTexture ( window , currentPage ) }
err = addDesireRow_Choice ( "Hair Texture" , "HairTexture" , editHairTextureDesirePage , "Donut" , "HairTexture" )
if ( err != nil ) { return nil , err }
editHasHIVDesirePage := func ( ) { setChooseDesiresPage_Infections ( window , currentPage ) }
err = addDesireRow_Choice ( "Has HIV" , "HasHIV" , editHasHIVDesirePage , "Donut" , "HasHIV" )
if ( err != nil ) { return nil , err }
editHasGenitalHerpesDesirePage := func ( ) { setChooseDesiresPage_Infections ( window , currentPage ) }
err = addDesireRow_Choice ( "Has Genital Herpes" , "HasGenitalHerpes" , editHasGenitalHerpesDesirePage , "Donut" , "HasGenitalHerpes" )
if ( err != nil ) { return nil , err }
foodNamesList := [ ] string {
"Fruit" ,
"Vegetables" ,
"Nuts" ,
"Grains" ,
"Dairy" ,
"Seafood" ,
"Beef" ,
"Pork" ,
"Poultry" ,
"Eggs" ,
"Beans" ,
}
for _ , foodName := range foodNamesList {
foodRatingDesireTitle := foodName + " Rating"
foodRatingDesireName := foodName + "Rating"
editFoodRatingDesirePage := func ( ) { setChooseDesiresPage_FoodRating ( window , foodName , currentPage ) }
err = addDesireRow_Choice ( foodRatingDesireTitle , foodRatingDesireName , editFoodRatingDesirePage , "Bar" , foodRatingDesireName )
if ( err != nil ) { return nil , err }
}
editFameDesirePage := func ( ) { setChooseDesiresPage_Fame ( window , currentPage ) }
err = addDesireRow_Choice ( "Fame" , "Fame" , editFameDesirePage , "Bar" , "Fame" )
if ( err != nil ) { return nil , err }
editAlcoholFrequencyDesirePage := func ( ) { setChooseDesiresPage_DrugFrequency ( window , "Alcohol" , currentPage ) }
err = addDesireRow_Choice ( "Alcohol Frequency" , "AlcoholFrequency" , editAlcoholFrequencyDesirePage , "Bar" , "AlcoholFrequency" )
if ( err != nil ) { return nil , err }
editTobaccoFrequencyDesirePage := func ( ) { setChooseDesiresPage_DrugFrequency ( window , "Tobacco" , currentPage ) }
err = addDesireRow_Choice ( "Tobacco Frequency" , "TobaccoFrequency" , editTobaccoFrequencyDesirePage , "Bar" , "TobaccoFrequency" )
if ( err != nil ) { return nil , err }
editCannabisFrequencyDesirePage := func ( ) { setChooseDesiresPage_DrugFrequency ( window , "Cannabis" , currentPage ) }
err = addDesireRow_Choice ( "Cannabis Frequency" , "CannabisFrequency" , editCannabisFrequencyDesirePage , "Bar" , "CannabisFrequency" )
if ( err != nil ) { return nil , err }
editGenderIdentityDesirePage := func ( ) { setChooseDesiresPage_GenderIdentity ( window , currentPage ) }
err = addDesireRow_Choice ( "Gender Identity" , "GenderIdentity" , editGenderIdentityDesirePage , "Donut" , "GenderIdentity" )
if ( err != nil ) { return nil , err }
editPetsRatingDesirePage := func ( ) { setChooseDesiresPage_Pets ( window , currentPage ) }
err = addDesireRow_Choice ( "Pets Rating" , "PetsRating" , editPetsRatingDesirePage , "Bar" , "PetsRating" )
if ( err != nil ) { return nil , err }
editDogsRatingDesirePage := func ( ) { setChooseDesiresPage_Pets ( window , currentPage ) }
err = addDesireRow_Choice ( "Dogs Rating" , "DogsRating" , editDogsRatingDesirePage , "Bar" , "DogsRating" )
if ( err != nil ) { return nil , err }
editCatsRatingDesirePage := func ( ) { setChooseDesiresPage_Pets ( window , currentPage ) }
err = addDesireRow_Choice ( "Cats Rating" , "CatsRating" , editCatsRatingDesirePage , "Bar" , "CatsRating" )
if ( err != nil ) { return nil , err }
editOffspringProbabilityOfAnyMonogenicDiseaseDesirePage := func ( ) { setChooseDesiresPage_MonogenicDiseases ( window , currentPage ) }
err = addDesireRow_Numerical ( "Offspring Probability Of Any Monogenic Disease" , "OffspringProbabilityOfAnyMonogenicDisease" , editOffspringProbabilityOfAnyMonogenicDiseaseDesirePage , "Donut" , "OffspringProbabilityOfAnyMonogenicDisease" )
if ( err != nil ) { return nil , err }
edit23andMeMaternalHaplogroupDesirePage := func ( ) { setChooseDesiresPage_23andMe_Haplogroup ( window , "Maternal" , currentPage ) }
err = addDesireRow_Choice ( "23andMe Maternal Haplogroup" , "23andMe_MaternalHaplogroup" , edit23andMeMaternalHaplogroupDesirePage , "Bar" , "23andMe_MaternalHaplogroup" )
if ( err != nil ) { return nil , err }
edit23andMePaternalHaplogroupDesirePage := func ( ) { setChooseDesiresPage_23andMe_Haplogroup ( window , "Paternal" , currentPage ) }
err = addDesireRow_Choice ( "23andMe Paternal Haplogroup" , "23andMe_PaternalHaplogroup" , edit23andMePaternalHaplogroupDesirePage , "Bar" , "23andMe_PaternalHaplogroup" )
if ( err != nil ) { return nil , err }
edit23andMeNeanderthalVariantsDesirePage := func ( ) { setChooseDesiresPage_23andMe_NeanderthalVariants ( window , currentPage ) }
err = addDesireRow_Numerical ( "23andMe Neanderthal Variants" , "23andMe_NeanderthalVariants" , edit23andMeNeanderthalVariantsDesirePage , "Donut" , "23andMe_NeanderthalVariants" )
if ( err != nil ) { return nil , err }
edit23andMeAncestryCompositionDesirePage := func ( ) { setChooseDesiresPage_23andMe_AncestryComposition ( window , "User" , currentPage ) }
err = addDesireRow_Custom ( "23andMe Ancestry Composition" , "23andMe_AncestryComposition" , edit23andMeAncestryCompositionDesirePage )
if ( err != nil ) { return nil , err }
editLanguageDesirePage := func ( ) { setChooseDesiresPage_Language ( window , currentPage ) }
err = addDesireRow_Custom ( "Language" , "Language" , editLanguageDesirePage )
if ( err != nil ) { return nil , err }
allDesiresGrid := container . NewHBox ( layout . NewSpacer ( ) , widget . NewSeparator ( ) , desireButtonsColumn , widget . NewSeparator ( ) , desireNameAndDataColumn , widget . NewSeparator ( ) , filterOptionChecksColumn , widget . NewSeparator ( ) , layout . NewSpacer ( ) )
return allDesiresGrid , nil
}
allDesiresGrid , err := getAllDesiresGrid ( )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , description , widget . NewSeparator ( ) , allDesiresGrid )
setPageContent ( page , window )
}
func setManageMateDownloadDesiresPage ( window fyne . Window , previousPage func ( ) ) {
currentPage := func ( ) { setManageMateDownloadDesiresPage ( window , previousPage ) }
title := getPageTitleCentered ( "My Mate Download Desires" )
backButton := getBackButtonCentered ( previousPage )
subtitle := getPageSubtitleCentered ( "My Mate Download Desires" )
description1 := getLabelCentered ( "Seekia downloads mate profiles from network hosts." )
description2 := getLabelCentered ( "These are servers run by volunteers." )
description3 := getLabelCentered ( "Your download desires are shared to hosts when you download profiles." )
description4 := getLabelCentered ( "These desires limit the profiles you download." )
description5 := getLabelCentered ( "You can choose how much information to share." )
description6 := getLabelCentered ( "The more desires you share, the less time it will take to download profiles." )
description7 := getLabelCentered ( "The hosts could be tracking this information, so more desires will reduce your privacy." )
description8 := getLabelCentered ( "All profiles are downloaded over the Tor anonymity network." )
chooseDesiresButton := getWidgetCentered ( widget . NewButtonWithIcon ( "Choose Desires" , theme . NavigateNextIcon ( ) , func ( ) {
setChooseMateDownloadDesiresPage ( window , currentPage )
} ) )
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , subtitle , widget . NewSeparator ( ) , description1 , description2 , description3 , description4 , description5 , description6 , description7 , description8 , chooseDesiresButton )
setPageContent ( page , window )
}
func setChooseMateDownloadDesiresPage ( window fyne . Window , previousPage func ( ) ) {
setLoadingScreen ( window , "Choose Mate Download Desires" , "Loading Download Desires..." )
currentPage := func ( ) { setChooseMateDownloadDesiresPage ( window , previousPage ) }
title := getPageTitleCentered ( "Choose Mate Download Desires" )
backButton := getBackButtonCentered ( previousPage )
description1 := getLabelCentered ( "You will share the selected desires with Hosts when you download profiles." )
description2 := getLabelCentered ( "These desires will not be displayed on your profile." )
description3 := getLabelCentered ( "Each desire will only be shared if you have enabled Filter All or Require Response" )
description4 := getLabelCentered ( "Select each desire you are comfortable sharing with hosts." )
//TODO: Add Help buttons to explain this better
// User should understand that the hosts will not necessarily know who they are.
// They will make requests over Tor, and their requestor fingerprint will be defined by these desires
// Each shared desire will increase the entropy of a requestor's fingerprint
// Most requestors will probably have a very unique fingerprint
//
// The challenge for malicious hosts will be to link a requestor fingerprint to a requestor's mate identity
// This may be difficult or easy, depending on how similar the requestor's desires are to their own profile
getDesiresGrid := func ( ) ( * fyne . Container , error ) {
desireTitlesColumn := container . NewVBox ( )
desireSelectChecksColumn := container . NewVBox ( )
desireNameLabel := getItalicLabelCentered ( "Desire Name:" )
shareDesireLabel := getItalicLabelCentered ( "Share Desire?" )
desireTitlesColumn . Add ( desireNameLabel )
desireSelectChecksColumn . Add ( shareDesireLabel )
desireTitlesColumn . Add ( widget . NewSeparator ( ) )
desireSelectChecksColumn . Add ( widget . NewSeparator ( ) )
allMyDownloadDesiresList := myMateCriteria . GetAllMyMateDownloadDesiresList ( )
for _ , desireName := range allMyDownloadDesiresList {
desireTitle , err := mateDesires . GetDesireTitleFromDesireName ( desireName )
if ( err != nil ) { return nil , err }
desireTitleLabel := getBoldLabelCentered ( translate ( desireTitle ) )
getDesireSelectCheck := func ( ) ( fyne . Widget , error ) {
selectCheck := widget . NewCheck ( "" , func ( selected bool ) {
err := myMateCriteria . SetShareMyDesireStatus ( desireName , selected )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , currentPage )
return
}
} )
isSelected , err := myMateCriteria . GetShareMyDesireStatus ( desireName )
if ( err != nil ) { return nil , err }
if ( isSelected == true ) {
selectCheck . Checked = true
}
return selectCheck , nil
}
desireSelectCheck , err := getDesireSelectCheck ( )
if ( err != nil ) { return nil , err }
desireSelectCheckCentered := getWidgetCentered ( desireSelectCheck )
desireTitlesColumn . Add ( desireTitleLabel )
desireSelectChecksColumn . Add ( desireSelectCheckCentered )
desireTitlesColumn . Add ( widget . NewSeparator ( ) )
desireSelectChecksColumn . Add ( widget . NewSeparator ( ) )
}
desiresGrid := container . NewHBox ( layout . NewSpacer ( ) , desireTitlesColumn , desireSelectChecksColumn , layout . NewSpacer ( ) )
return desiresGrid , nil
}
desiresGrid , err := getDesiresGrid ( )
if ( err != nil ) {
setErrorEncounteredPage ( window , err , previousPage )
return
}
page := container . NewVBox ( title , backButton , widget . NewSeparator ( ) , description1 , description2 , description3 , description4 , widget . NewSeparator ( ) , desiresGrid )
setPageContent ( page , window )
}