672 lines
21 KiB
Go
672 lines
21 KiB
Go
|
package gui
|
||
|
|
||
|
// viewContentGui.go implements a page used by moderators to browse content
|
||
|
|
||
|
import "fyne.io/fyne/v2"
|
||
|
import "fyne.io/fyne/v2/container"
|
||
|
import "fyne.io/fyne/v2/widget"
|
||
|
import "fyne.io/fyne/v2/layout"
|
||
|
import "fyne.io/fyne/v2/theme"
|
||
|
import "fyne.io/fyne/v2/data/binding"
|
||
|
|
||
|
import "seekia/internal/appMemory"
|
||
|
import "seekia/internal/encoding"
|
||
|
import "seekia/internal/helpers"
|
||
|
import "seekia/internal/moderation/contentControversy"
|
||
|
import "seekia/internal/moderation/reviewStorage"
|
||
|
import "seekia/internal/moderation/viewedContent"
|
||
|
import "seekia/internal/mySettings"
|
||
|
import "seekia/internal/network/appNetworkType/getAppNetworkType"
|
||
|
|
||
|
import "time"
|
||
|
import "errors"
|
||
|
|
||
|
// The viewedContent page provides a way for moderators to view, filter and sort all stored content
|
||
|
// One use of this is to sort content by controversy, to find moderators to ban
|
||
|
|
||
|
func setBrowseContentPage(window fyne.Window, previousPage func()){
|
||
|
|
||
|
appMemory.SetMemoryEntry("CurrentViewedPage", "BrowseContent")
|
||
|
|
||
|
checkIfPageHasChangedFunction := func()bool{
|
||
|
exists, currentViewedPage := appMemory.GetMemoryEntry("CurrentViewedPage")
|
||
|
if (exists == false || currentViewedPage != "BrowseContent"){
|
||
|
return true
|
||
|
}
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
//TODO: Check if moderator/host mode is enabled
|
||
|
// If not, we cannot calculate many of the attributes
|
||
|
// We should let the user know that somehow
|
||
|
|
||
|
currentPage := func(){setBrowseContentPage(window, previousPage)}
|
||
|
|
||
|
title := getPageTitleCentered("Browse Content")
|
||
|
|
||
|
backButton := getBackButtonCentered(previousPage)
|
||
|
|
||
|
statsIcon, err := getFyneImageIcon("Stats")
|
||
|
if (err != nil){
|
||
|
setErrorEncounteredPage(window, err, previousPage)
|
||
|
return
|
||
|
}
|
||
|
statsButton := widget.NewButton("Stats", func(){
|
||
|
//TODO: A page to view statistics about all stored content
|
||
|
showUnderConstructionDialog(window)
|
||
|
})
|
||
|
statsButtonWithIcon := container.NewGridWithRows(2, statsIcon, statsButton)
|
||
|
|
||
|
filtersIcon, err := getFyneImageIcon("Desires")
|
||
|
if (err != nil){
|
||
|
setErrorEncounteredPage(window, err, previousPage)
|
||
|
return
|
||
|
}
|
||
|
filtersButton := widget.NewButton("Filters", func(){
|
||
|
//TODO: A page to configure filters for the viewed content
|
||
|
// Examples:
|
||
|
// -Only show content created between a certain time frame
|
||
|
// -Only show content authored by certain identity types
|
||
|
// -Only show a certain contentType (Profile/Message)
|
||
|
showUnderConstructionDialog(window)
|
||
|
})
|
||
|
filtersButtonWithIcon := container.NewGridWithRows(2, filtersIcon, filtersButton)
|
||
|
|
||
|
controversyIcon, err := getFyneImageIcon("Controversy")
|
||
|
if (err != nil){
|
||
|
setErrorEncounteredPage(window, err, previousPage)
|
||
|
return
|
||
|
}
|
||
|
controversyButton := widget.NewButton("Controversy", func(){
|
||
|
//TODO: A page to tune the controversy calculation parameters
|
||
|
showUnderConstructionDialog(window)
|
||
|
})
|
||
|
controversyButtonWithIcon := container.NewGridWithRows(2, controversyIcon, controversyButton)
|
||
|
|
||
|
pageButtonsRow := getContainerCentered(container.NewGridWithRows(1, controversyButtonWithIcon, filtersButtonWithIcon, statsButtonWithIcon))
|
||
|
|
||
|
currentSortByAttribute, err := viewedContent.GetViewedContentSortByAttribute()
|
||
|
if (err != nil) {
|
||
|
setErrorEncounteredPage(window, err, previousPage)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
sortingByLabel := getBoldLabel(translate("Sorting By:"))
|
||
|
|
||
|
getSortByAttributeTitle := func()string{
|
||
|
|
||
|
if (currentSortByAttribute == "BanAdvocates"){
|
||
|
result := translate("Ban Advocates")
|
||
|
return result
|
||
|
}
|
||
|
if (currentSortByAttribute == "NumberOfReviewers"){
|
||
|
result := translate("Number Of Reviewers")
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
result := translate(currentSortByAttribute)
|
||
|
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
sortByAttributeTitle := getSortByAttributeTitle()
|
||
|
|
||
|
sortByAttributeButton := widget.NewButton(sortByAttributeTitle, func(){
|
||
|
setSelectViewedContentSortByAttributePage(window, currentPage)
|
||
|
})
|
||
|
|
||
|
getSortDirectionButtonWithIcon := func()(fyne.Widget, error){
|
||
|
|
||
|
currentSortDirection, err := viewedContent.GetViewedContentSortDirection()
|
||
|
if (err != nil) { return nil, err }
|
||
|
|
||
|
if (currentSortDirection == "Ascending"){
|
||
|
button := widget.NewButtonWithIcon(translate("Ascending"), theme.MoveUpIcon(), func(){
|
||
|
appMemory.SetMemoryEntry("StopBuildViewedContentYesNo", "Yes")
|
||
|
_ = mySettings.SetSetting("ViewedContentSortDirection", "Descending")
|
||
|
_ = mySettings.SetSetting("ViewedContentSortedStatus", "No")
|
||
|
_ = mySettings.SetSetting("ViewedContentViewIndex", "0")
|
||
|
currentPage()
|
||
|
})
|
||
|
return button, nil
|
||
|
}
|
||
|
|
||
|
button := widget.NewButtonWithIcon(translate("Descending"), theme.MoveDownIcon(), func(){
|
||
|
appMemory.SetMemoryEntry("StopBuildViewedContentYesNo", "Yes")
|
||
|
_ = mySettings.SetSetting("ViewedContentSortDirection", "Ascending")
|
||
|
_ = mySettings.SetSetting("ViewedContentSortedStatus", "No")
|
||
|
_ = mySettings.SetSetting("ViewedContentViewIndex", "0")
|
||
|
currentPage()
|
||
|
})
|
||
|
return button, nil
|
||
|
}
|
||
|
|
||
|
sortByDirectionButton, err := getSortDirectionButtonWithIcon()
|
||
|
if (err != nil) {
|
||
|
setErrorEncounteredPage(window, err, previousPage)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
sortByRow := container.NewHBox(layout.NewSpacer(), sortingByLabel, sortByAttributeButton, sortByDirectionButton, layout.NewSpacer())
|
||
|
|
||
|
appNetworkType, err := getAppNetworkType.GetAppNetworkType()
|
||
|
if (err != nil) {
|
||
|
setErrorEncounteredPage(window, err, previousPage)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
viewedContentReady, err := viewedContent.GetViewedContentIsReadyStatus(appNetworkType)
|
||
|
if (err != nil) {
|
||
|
setErrorEncounteredPage(window, err, previousPage)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if (viewedContentReady == false){
|
||
|
|
||
|
progressPercentageBinding := binding.NewFloat()
|
||
|
sortingDetailsBinding := binding.NewString()
|
||
|
|
||
|
startUpdateViewedContentAndLoadingBarFunction := func(){
|
||
|
|
||
|
err := viewedContent.StartUpdatingViewedContent(appNetworkType)
|
||
|
if (err != nil) {
|
||
|
setErrorEncounteredPage(window, err, previousPage)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
sortingDetailsBindingSet := false
|
||
|
|
||
|
var encounteredError error
|
||
|
|
||
|
for{
|
||
|
|
||
|
pageHasChanged := checkIfPageHasChangedFunction()
|
||
|
if (pageHasChanged == true){
|
||
|
appMemory.SetMemoryEntry("StopBuildViewedContentYesNo", "Yes")
|
||
|
return
|
||
|
}
|
||
|
|
||
|
buildEncounteredError, errorEncounteredString, buildIsStopped, contentIsReady, currentPercentageProgress, err := viewedContent.GetViewedContentBuildStatus(appNetworkType)
|
||
|
if (err != nil){
|
||
|
encounteredError = err
|
||
|
break
|
||
|
}
|
||
|
|
||
|
if (buildEncounteredError == true){
|
||
|
encounteredError = errors.New(errorEncounteredString)
|
||
|
break
|
||
|
}
|
||
|
|
||
|
if (buildIsStopped == true){
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if (contentIsReady == 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 && sortingDetailsBindingSet == false){
|
||
|
|
||
|
numberOfContents, err := viewedContent.GetNumberOfGeneratedViewedContents()
|
||
|
if (err != nil) {
|
||
|
encounteredError = err
|
||
|
break
|
||
|
}
|
||
|
if (numberOfContents != 0){
|
||
|
|
||
|
numberOfContentsString := helpers.ConvertIntToString(numberOfContents)
|
||
|
sortingDetailsBinding.Set("Sorting " + numberOfContentsString + " Contents...")
|
||
|
}
|
||
|
|
||
|
sortingDetailsBindingSet = true
|
||
|
}
|
||
|
|
||
|
time.Sleep(100 * time.Millisecond)
|
||
|
}
|
||
|
|
||
|
// This is only reached if an error is encountered during build
|
||
|
|
||
|
errorToShow := errors.New("Error encountered during build of viewed content: " + encounteredError.Error())
|
||
|
|
||
|
setErrorEncounteredPage(window, errorToShow, previousPage)
|
||
|
}
|
||
|
|
||
|
loadingLabel := getBoldLabelCentered("Loading Content...")
|
||
|
|
||
|
loadingBar := getWidgetCentered(widget.NewProgressBarWithData(progressPercentageBinding))
|
||
|
|
||
|
loadingDetailsLabel := widget.NewLabelWithData(sortingDetailsBinding)
|
||
|
loadingDetailsLabel.TextStyle = getFyneTextStyle_Italic()
|
||
|
loadingDetailsLabelCentered := getWidgetCentered(loadingDetailsLabel)
|
||
|
|
||
|
page := container.NewVBox(title, backButton, widget.NewSeparator(), pageButtonsRow, widget.NewSeparator(), sortByRow, widget.NewSeparator(), loadingLabel, loadingBar, loadingDetailsLabelCentered)
|
||
|
|
||
|
setPageContent(page, window)
|
||
|
|
||
|
go startUpdateViewedContentAndLoadingBarFunction()
|
||
|
|
||
|
return
|
||
|
}
|
||
|
|
||
|
getResultsContainer := func()(*fyne.Container, error){
|
||
|
|
||
|
getRefreshResultsButtonText := func()(string, error){
|
||
|
needsRefresh, err := viewedContent.CheckIfViewedContentNeedsRefresh()
|
||
|
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("ViewedContentGeneratedStatus", "No")
|
||
|
_ = mySettings.SetSetting("ViewedContentViewIndex", "0")
|
||
|
currentPage()
|
||
|
}))
|
||
|
|
||
|
viewedContentIsReady, currentViewedContentList, err := viewedContent.GetViewedContentList(appNetworkType)
|
||
|
if (err != nil) { return nil, err }
|
||
|
if (viewedContentIsReady == false){
|
||
|
return nil, errors.New("Viewed content is not ready after earlier check determined it was ready.")
|
||
|
}
|
||
|
|
||
|
numberOfViewedContents := len(currentViewedContentList)
|
||
|
|
||
|
if (numberOfViewedContents == 0){
|
||
|
|
||
|
noContentFoundLabel := getBoldLabelCentered("No content found.")
|
||
|
|
||
|
numberOfFilters, err := viewedContent.GetNumberOfActiveViewedContentFilters()
|
||
|
if (err != nil) { return nil, err }
|
||
|
if (numberOfFilters == 0){
|
||
|
noContentFoundWithRefreshButton := container.NewVBox(noContentFoundLabel, refreshResultsButton)
|
||
|
return noContentFoundWithRefreshButton, nil
|
||
|
}
|
||
|
|
||
|
numberOfFiltersString := helpers.ConvertIntToString(numberOfFilters)
|
||
|
|
||
|
getActiveFiltersText := func()string{
|
||
|
if (numberOfFilters == 1){
|
||
|
return "active filter"
|
||
|
}
|
||
|
return "active filters"
|
||
|
}
|
||
|
|
||
|
activeFiltersText := getActiveFiltersText()
|
||
|
|
||
|
activeFiltersLabel := getLabelCentered(numberOfFiltersString + " " + activeFiltersText)
|
||
|
|
||
|
noContentFoundWithFiltersInfo := container.NewVBox(noContentFoundLabel, activeFiltersLabel, refreshResultsButton)
|
||
|
|
||
|
return noContentFoundWithFiltersInfo, nil
|
||
|
}
|
||
|
|
||
|
getCurrentViewIndex := func()(int, error){
|
||
|
exists, viewIndexString, err := mySettings.GetSetting("ViewedContentViewIndex")
|
||
|
if (err != nil) { return 0, err }
|
||
|
if (exists == false){
|
||
|
return 0, nil
|
||
|
}
|
||
|
|
||
|
viewIndex, err := helpers.ConvertStringToInt(viewIndexString)
|
||
|
if (err != nil){
|
||
|
return 0, errors.New("MySettings invalid: Invalid ViewedContentViewIndex: " + viewIndexString)
|
||
|
}
|
||
|
if (viewIndex < 0) {
|
||
|
return 0, nil
|
||
|
}
|
||
|
|
||
|
maximumViewIndex := numberOfViewedContents-1
|
||
|
if (viewIndex > maximumViewIndex){
|
||
|
|
||
|
return maximumViewIndex, nil
|
||
|
}
|
||
|
return viewIndex, nil
|
||
|
}
|
||
|
|
||
|
viewIndex, err := getCurrentViewIndex()
|
||
|
if (err != nil) { return nil, err }
|
||
|
|
||
|
getNavigateToBeginningButton := func()fyne.Widget{
|
||
|
|
||
|
if (numberOfViewedContents <= 5 || viewIndex == 0){
|
||
|
|
||
|
emptyButton := widget.NewButton(" ", nil)
|
||
|
|
||
|
return emptyButton
|
||
|
}
|
||
|
|
||
|
goToBeginningButton := widget.NewButtonWithIcon("", theme.MediaSkipPreviousIcon(), func(){
|
||
|
_ = mySettings.SetSetting("ViewedContentViewIndex", "0")
|
||
|
currentPage()
|
||
|
})
|
||
|
|
||
|
return goToBeginningButton
|
||
|
}
|
||
|
|
||
|
getNavigateToEndButton := func()fyne.Widget{
|
||
|
|
||
|
emptyButton := widget.NewButton(" ", nil)
|
||
|
|
||
|
if (numberOfViewedContents <= 5){
|
||
|
return emptyButton
|
||
|
}
|
||
|
|
||
|
finalPageMinimumIndex := numberOfViewedContents - 5
|
||
|
|
||
|
if (viewIndex >= finalPageMinimumIndex){
|
||
|
return emptyButton
|
||
|
}
|
||
|
|
||
|
goToEndButton := widget.NewButtonWithIcon("", theme.MediaSkipNextIcon(), func(){
|
||
|
finalPageIndexString := helpers.ConvertIntToString(finalPageMinimumIndex)
|
||
|
_ = mySettings.SetSetting("ViewedContentViewIndex", finalPageIndexString)
|
||
|
currentPage()
|
||
|
})
|
||
|
|
||
|
return goToEndButton
|
||
|
}
|
||
|
|
||
|
getNavigateLeftButton := func()fyne.Widget{
|
||
|
|
||
|
if (numberOfViewedContents <= 5 || viewIndex == 0){
|
||
|
|
||
|
emptyButton := widget.NewButton(" ", nil)
|
||
|
return emptyButton
|
||
|
}
|
||
|
|
||
|
leftButton := widget.NewButtonWithIcon("", theme.NavigateBackIcon(), func(){
|
||
|
newIndex := helpers.ConvertIntToString(viewIndex-5)
|
||
|
_ = mySettings.SetSetting("ViewedContentViewIndex", newIndex)
|
||
|
currentPage()
|
||
|
})
|
||
|
|
||
|
return leftButton
|
||
|
}
|
||
|
|
||
|
getNavigateRightButton := func()fyne.Widget{
|
||
|
|
||
|
emptyButton := widget.NewButton(" ", nil)
|
||
|
|
||
|
if (numberOfViewedContents <= 5){
|
||
|
|
||
|
return emptyButton
|
||
|
}
|
||
|
|
||
|
finalPageMinimumIndex := numberOfViewedContents - 5
|
||
|
|
||
|
if (viewIndex >= finalPageMinimumIndex){
|
||
|
return emptyButton
|
||
|
}
|
||
|
|
||
|
rightButton := widget.NewButtonWithIcon("", theme.NavigateNextIcon(), func(){
|
||
|
newIndex := helpers.ConvertIntToString(viewIndex+5)
|
||
|
_ = mySettings.SetSetting("ViewedContentViewIndex", newIndex)
|
||
|
currentPage()
|
||
|
})
|
||
|
|
||
|
return rightButton
|
||
|
}
|
||
|
|
||
|
getViewedContentInfoRow := func()*fyne.Container{
|
||
|
|
||
|
numberOfViewedContentsString := helpers.ConvertIntToString(numberOfViewedContents)
|
||
|
|
||
|
getResultOrResultsText := func()string{
|
||
|
if (numberOfViewedContents == 1){
|
||
|
return "Result"
|
||
|
}
|
||
|
return "Results"
|
||
|
}
|
||
|
|
||
|
resultOrResultsText := getResultOrResultsText()
|
||
|
|
||
|
numberOfViewedContentsLabel := getBoldLabel("Viewing " + numberOfViewedContentsString + " " + resultOrResultsText)
|
||
|
|
||
|
if (numberOfViewedContents <= 5){
|
||
|
viewedContentInfoRow := getWidgetCentered(numberOfViewedContentsLabel)
|
||
|
return viewedContentInfoRow
|
||
|
}
|
||
|
|
||
|
navigateToBeginningButton := getNavigateToBeginningButton()
|
||
|
navigateToEndButton := getNavigateToEndButton()
|
||
|
navigateLeftButton := getNavigateLeftButton()
|
||
|
navigateRightButton := getNavigateRightButton()
|
||
|
|
||
|
viewedContentInfoRow := container.NewHBox(layout.NewSpacer(), navigateToBeginningButton, navigateLeftButton, numberOfViewedContentsLabel, navigateRightButton, navigateToEndButton, layout.NewSpacer())
|
||
|
|
||
|
return viewedContentInfoRow
|
||
|
}
|
||
|
|
||
|
viewedContentInfoRow := getViewedContentInfoRow()
|
||
|
|
||
|
viewIndexOnwardsViewedContentList := currentViewedContentList[viewIndex:]
|
||
|
|
||
|
contentResultsContainer := container.NewVBox()
|
||
|
|
||
|
if (viewIndex == 0){
|
||
|
contentResultsContainer.Add(refreshResultsButton)
|
||
|
contentResultsContainer.Add(widget.NewSeparator())
|
||
|
}
|
||
|
|
||
|
emptyLabel1 := widget.NewLabel("")
|
||
|
contentHashTitle := getItalicLabelCentered("Content Hash")
|
||
|
contentTypeTitle := getItalicLabelCentered("Content Type")
|
||
|
featuredAttributeTitle := getItalicLabelCentered(sortByAttributeTitle)
|
||
|
emptyLabel2 := widget.NewLabel("")
|
||
|
|
||
|
contentIndexColumn := container.NewVBox(emptyLabel1, widget.NewSeparator())
|
||
|
contentHashColumn := container.NewVBox(contentHashTitle, widget.NewSeparator())
|
||
|
contentTypeColumn := container.NewVBox(contentTypeTitle, widget.NewSeparator())
|
||
|
featuredAttributeColumn := container.NewVBox(featuredAttributeTitle, widget.NewSeparator())
|
||
|
viewContentButtonsColumn := container.NewVBox(emptyLabel2, widget.NewSeparator())
|
||
|
|
||
|
for index, contentHashString := range viewIndexOnwardsViewedContentList{
|
||
|
|
||
|
resultIndex := viewIndex + index + 1
|
||
|
resultIndexString := helpers.ConvertIntToString(resultIndex)
|
||
|
|
||
|
resultIndexLabel := getBoldLabelCentered(resultIndexString + ".")
|
||
|
|
||
|
contentHash, err := encoding.DecodeHexStringToBytes(contentHashString)
|
||
|
if (err != nil){
|
||
|
return nil, errors.New("Viewed content list contains invalid contentHash: " + contentHashString)
|
||
|
}
|
||
|
|
||
|
contentType, err := helpers.GetContentTypeFromContentHash(contentHash)
|
||
|
if (err != nil) { return nil, err }
|
||
|
if (contentType != "Profile" && contentType != "Message"){
|
||
|
return nil, errors.New("Viewed content list contains invalid contentHash: " + contentHashString)
|
||
|
}
|
||
|
|
||
|
getFeaturedAttributeValue := func()(string, error){
|
||
|
|
||
|
unknownTranslated := translate("Unknown")
|
||
|
|
||
|
if (currentSortByAttribute == "Controversy"){
|
||
|
|
||
|
controversyIsKnown, controversyRating, err := contentControversy.GetContentControversyRating(contentHash)
|
||
|
if (err != nil) { return "", err }
|
||
|
if (controversyIsKnown == false){
|
||
|
return unknownTranslated, nil
|
||
|
}
|
||
|
|
||
|
controversyRatingString := helpers.ConvertInt64ToString(controversyRating)
|
||
|
return controversyRatingString, nil
|
||
|
}
|
||
|
if (currentSortByAttribute == "NumberOfReviewers"){
|
||
|
|
||
|
if (contentType == "Profile"){
|
||
|
|
||
|
if (len(contentHash) != 28){
|
||
|
return "", errors.New("GetContentTypeFromContentHash returning Profile for different length content hash.")
|
||
|
}
|
||
|
|
||
|
profileHash := [28]byte(contentHash)
|
||
|
|
||
|
profileMetadataIsKnown, downloadingRequiredData, numberOfReviewers, err := reviewStorage.GetNumberOfProfileReviewers(profileHash)
|
||
|
if (err != nil) { return "", err }
|
||
|
if (profileMetadataIsKnown == false || downloadingRequiredData == false){
|
||
|
return unknownTranslated, nil
|
||
|
}
|
||
|
|
||
|
numberOfReviewersString := helpers.ConvertIntToString(numberOfReviewers)
|
||
|
|
||
|
return numberOfReviewersString, nil
|
||
|
|
||
|
}
|
||
|
// contentType == "Message"
|
||
|
|
||
|
if (len(contentHash) != 26){
|
||
|
return "", errors.New("GetContentTypeFromContentHash returning Message for different length content hash.")
|
||
|
}
|
||
|
|
||
|
messageHash := [26]byte(contentHash)
|
||
|
|
||
|
messageMetadataIsKnown, downloadingRequiredData, numberOfReviewers, err := reviewStorage.GetNumberOfMessageReviewers(messageHash)
|
||
|
if (err != nil) { return "", err }
|
||
|
if (messageMetadataIsKnown == false || downloadingRequiredData == false){
|
||
|
return unknownTranslated, nil
|
||
|
}
|
||
|
|
||
|
numberOfReviewersString := helpers.ConvertIntToString(numberOfReviewers)
|
||
|
return numberOfReviewersString, nil
|
||
|
}
|
||
|
|
||
|
return "", errors.New("Unknown featured attribute: " + currentSortByAttribute)
|
||
|
}
|
||
|
|
||
|
featuredAttributeValue, err := getFeaturedAttributeValue()
|
||
|
if (err != nil) { return nil, err }
|
||
|
|
||
|
featuredAttributeLabel := getBoldLabelCentered(featuredAttributeValue)
|
||
|
|
||
|
contentTypeLabel := getBoldLabelCentered(translate(contentType))
|
||
|
|
||
|
contentHashTrimmed, _, err := helpers.TrimAndFlattenString(contentHashString, 7)
|
||
|
if (err != nil) { return nil, err }
|
||
|
contentHashLabel := getBoldLabelCentered(contentHashTrimmed)
|
||
|
|
||
|
viewContentButton := widget.NewButtonWithIcon("View Details", theme.VisibilityIcon(), func(){
|
||
|
if (contentType == "Message"){
|
||
|
|
||
|
if (len(contentHash) != 26){
|
||
|
setErrorEncounteredPage(window, errors.New("GetContentTypeFromContentHash returning Message for different length content hash."), currentPage)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
messageHash := [26]byte(contentHash)
|
||
|
|
||
|
setViewMessageModerationDetailsPage(window, messageHash, currentPage)
|
||
|
|
||
|
} else if (contentType == "Profile"){
|
||
|
|
||
|
if (len(contentHash) != 28){
|
||
|
setErrorEncounteredPage(window, errors.New("GetContentTypeFromContentHash returning Profile for different length content hash."), currentPage)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
profileHash := [28]byte(contentHash)
|
||
|
|
||
|
setViewProfileModerationDetailsPage(window, profileHash, currentPage)
|
||
|
}
|
||
|
})
|
||
|
|
||
|
contentIndexColumn.Add(resultIndexLabel)
|
||
|
contentHashColumn.Add(contentHashLabel)
|
||
|
contentTypeColumn.Add(contentTypeLabel)
|
||
|
featuredAttributeColumn.Add(featuredAttributeLabel)
|
||
|
viewContentButtonsColumn.Add(viewContentButton)
|
||
|
|
||
|
contentIndexColumn.Add(widget.NewSeparator())
|
||
|
contentHashColumn.Add(widget.NewSeparator())
|
||
|
contentTypeColumn.Add(widget.NewSeparator())
|
||
|
featuredAttributeColumn.Add(widget.NewSeparator())
|
||
|
viewContentButtonsColumn.Add(widget.NewSeparator())
|
||
|
|
||
|
if (index >= 4){
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
|
||
|
gridInfoRowWithSeparator := container.NewVBox(viewedContentInfoRow, widget.NewSeparator())
|
||
|
|
||
|
resultsGrid := container.NewHBox(layout.NewSpacer(), contentIndexColumn, contentHashColumn, contentTypeColumn, featuredAttributeColumn, viewContentButtonsColumn, layout.NewSpacer())
|
||
|
|
||
|
contentResultsContainer.Add(resultsGrid)
|
||
|
|
||
|
viewedContentContainerScrollable := container.NewVScroll(contentResultsContainer)
|
||
|
|
||
|
resultsContainer := container.NewBorder(gridInfoRowWithSeparator, nil, nil, nil, viewedContentContainerScrollable)
|
||
|
|
||
|
return resultsContainer, nil
|
||
|
}
|
||
|
|
||
|
resultsContainer, err := getResultsContainer()
|
||
|
if (err != nil){
|
||
|
setErrorEncounteredPage(window, err, previousPage)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
header := container.NewVBox(title, backButton, widget.NewSeparator(), pageButtonsRow, widget.NewSeparator(), sortByRow, widget.NewSeparator())
|
||
|
|
||
|
page := container.NewBorder(header, nil, nil, nil, resultsContainer)
|
||
|
|
||
|
setPageContent(page, window)
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
func setSelectViewedContentSortByAttributePage(window fyne.Window, previousPage func()){
|
||
|
|
||
|
appMemory.SetMemoryEntry("CurrentViewedPage", "ViewedContentSortBySelect")
|
||
|
|
||
|
title := getPageTitleCentered("Select Sort By Attribute")
|
||
|
|
||
|
backButton := getBackButtonCentered(previousPage)
|
||
|
|
||
|
description := getLabelCentered("Select the attribute to sort the viewed content by.")
|
||
|
|
||
|
getSelectButton := func(attributeTitle string, attributeName string, sortDirection string) fyne.Widget{
|
||
|
|
||
|
button := widget.NewButton(attributeTitle, func(){
|
||
|
_ = mySettings.SetSetting("ViewedContentSortedStatus", "No")
|
||
|
_ = mySettings.SetSetting("ViewedContentSortByAttribute", attributeName)
|
||
|
_ = mySettings.SetSetting("ViewedContentSortDirection", sortDirection)
|
||
|
_ = mySettings.SetSetting("ViewedContentViewIndex", "0")
|
||
|
|
||
|
previousPage()
|
||
|
})
|
||
|
|
||
|
return button
|
||
|
}
|
||
|
|
||
|
//TODO: Add more attributes
|
||
|
|
||
|
controversyButton := getSelectButton("Controversy", "Controversy", "Ascending")
|
||
|
numberOfReviewersButton := getSelectButton("Number Of Reviewers", "NumberOfReviewers", "Descending")
|
||
|
|
||
|
buttonsGrid := getContainerCentered(container.NewGridWithColumns(1, controversyButton, numberOfReviewersButton))
|
||
|
|
||
|
content := container.NewVBox(title, backButton, widget.NewSeparator(), description, widget.NewSeparator(), buttonsGrid)
|
||
|
|
||
|
setPageContent(content, window)
|
||
|
}
|
||
|
|
||
|
|
||
|
|