Skip to content

Commit

Permalink
Merge pull request #141 from RightToAskOrg/plaintext-votes-2
Browse files Browse the repository at this point in the history
Plaintext votes 2
  • Loading branch information
vteague authored Dec 13, 2022
2 parents c6346c3 + 5475eca commit 929b144
Show file tree
Hide file tree
Showing 20 changed files with 448 additions and 295 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ public static class Constants
public static string IsVerifiedMPAccount = "IsVerifiedMPAccount";
public static string MPRegisteredAs= "MPRegisteredAs";
public static string Address = "Address";
public static string DownvotedQuestions = "DownvotedQuestions";
public static string UpvotedQuestions = "UpvotedQuestions";
public static string DismissedQuestions = "DismissedQuestions";
public static string ReportedQuestions = "ReportedQuestions";

// Special numbers
public static float similarityThreshold = 2.5F;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;

public class TriedToUploadWhileNotRegisteredException : Exception
{
public TriedToUploadWhileNotRegisteredException()
{
}

public TriedToUploadWhileNotRegisteredException(string message)
: base(message)
{
}

public TriedToUploadWhileNotRegisteredException(string message, Exception inner)
: base(message, inner)
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public static class RTAClient
private static readonly string EditUserUrl = BaseUrl + "/edit_user";
private static readonly string QnUrl = BaseUrl + "/new_question";
private static readonly string EditQnUrl = BaseUrl + "/edit_question";
private static readonly string PlaintextVoteQnUrl = BaseUrl + "/plaintext_vote_question";
private static readonly string MPListUrl = BaseUrl + "/MPs.json";
private static readonly string CommitteeListUrl = BaseUrl + "/committees.json";
private static readonly string HearingsListUrl = BaseUrl + "/hearings.json";
Expand Down Expand Up @@ -154,6 +155,11 @@ public static async Task<JOSResult<string>> UpdateExistingQuestion(QuestionSendT
{
return await SignAndSendDataToServer(existingQuestion, AppResources.QuestionErrorTypeDescription, EditQnUrl, "Error editing question", uid);
}

public static async Task<JOSResult<string>> SendPlaintextUpvote(PlainTextVoteOnQuestionCommand voteOnQuestion, string uid)
{
return await SignAndSendDataToServer(voteOnQuestion, AppResources.QuestionErrorTypeDescription, PlaintextVoteQnUrl, "Error voting on question", uid);
}

public static async Task<JOSResult<string>> RequestEmailValidation(ClientSignedUnparsed signedMsg, string email)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,7 @@ namespace RightToAskClient.Models
public class FilterChoices : INotifyPropertyChanged
{
private string _searchKeyword = "";
// private ObservableCollection<MP> _selectedAnsweringMPs = new ObservableCollection<MP>();
// private ObservableCollection<MP> _selectedAnsweringMPsMine = new ObservableCollection<MP>();
// private ObservableCollection<MP> _selectedAskingMPs = new ObservableCollection<MP>();
// private ObservableCollection<MP> _selectedAskingMPsMine = new ObservableCollection<MP>();
// private ObservableCollection<Authority> _selectedAuthorities = new ObservableCollection<Authority>();
// private ObservableCollection<string> _selectedAskingCommittee = new ObservableCollection<string>();
//
//private ObservableCollection<Person?> _selectedAskingUsers = new ObservableCollection<Person?>();

private SelectableList<Person> _questionWriterLists
= new SelectableList<Person>(new List<Person>(), new List<Person>());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@ public static IndividualParticipant getInstance()
public bool AddressUpdated { get; set; }
public bool HasQuestions { get; set; }

// needs to be accessible on a few pages and VMs so I put it here
public List<string> UpvotedQuestionIDs { get; set; } = new List<string>();
public List<string> ReportedQuestionIDs { get; set; } = new List<string>();
public List<string> RemovedQuestionIDs { get; set; } = new List<string>();

public ClientSignedUnparsed SignMessage<T>(T message)
{
Expand Down
120 changes: 24 additions & 96 deletions RightToAskClient/RightToAskClient/RightToAskClient/Models/Question.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ public enum QuestionDetailsStatus

public class Question : ObservableObject
{
// Note these relate to whether this user up- or down-voted the question, not the global tally.
private int _upVotesByThisUser;
private int _downVotesByThisUser;

public QuestionDetailsStatus Status { get; set; }

private string _questionText = "";
Expand All @@ -36,7 +32,6 @@ public string QuestionText
set
{
SetProperty(ref _questionText, value);
//** QuestionViewModel.Instance.ServerQuestionUpdates.question_text = _questionText;
Updates.question_text = _questionText;
}
}
Expand Down Expand Up @@ -137,22 +132,6 @@ public RTAPermissions WhoShouldAnswerTheQuestionPermissions
}
}

public string QuestionAnswerers =>
Extensions.JoinFilter(", ",
string.Join(", ",Filters.SelectedAnsweringMPsNotMine.Select(mp => mp.ShortestName)),
string.Join(", ",Filters.SelectedAnsweringMPsMine.Select(mp => mp.ShortestName)),
string.Join(", ",Filters.SelectedAuthorities.Select(a => a.ShortestName)));

// The MPs or committee who are meant to ask the question
public string QuestionAskers =>
Extensions.JoinFilter(", ",
string.Join(", ", Filters.SelectedAskingMPsNotMine.Select(mp => mp.ShortestName)),
string.Join(", ", Filters.SelectedAskingMPsMine.Select(mp => mp.ShortestName)),
string.Join(",", Filters.SelectedCommittees.Select(com => com.ShortestName)));
// TODO add:
// + String.Join(",",Filters.SelectedAskingUsers.Select(....));



// Whether the person writing the question allows other users to add QuestionAnswerers
private RTAPermissions _whoShouldAskTheQuestionPermissions;
Expand Down Expand Up @@ -181,25 +160,11 @@ public List<Uri> HansardLink
//** QuestionViewModel.Instance.ServerQuestionUpdates.hansard_link = _hansardLink;
}

public int UpVotesByThisUser
{
get => _upVotesByThisUser;
set => SetProperty(ref _upVotesByThisUser, value);
}
public int DownVotesByThisUser
{
get => _downVotesByThisUser;
set
{
_downVotesByThisUser = value;
OnPropertyChanged();
}
}
private bool _alreadyUpvoted;
public bool AlreadyUpvoted
{
get => _alreadyUpvoted;
set => SetProperty(ref _alreadyUpvoted, value);
private set => SetProperty(ref _alreadyUpvoted, value);
}

private bool _alreadyReported;
Expand All @@ -216,73 +181,22 @@ public bool HasAnswer
set => SetProperty(ref _hasAnswer, value);
}

// constructor needed for command creation
// Explicit empty constructor, for use in the case we're generating our own question.
public Question()
{
UpvoteCommand = new Command(async () =>

{
// can only upvote questions if you are registered
if (IndividualParticipant.getInstance().ProfileData.RegistrationInfo.IsRegistered)
{
if (!AlreadyUpvoted)
{
UpVotesByThisUser += 1;
AlreadyUpvoted = true;
IndividualParticipant.getInstance().UpvotedQuestionIDs.Add(QuestionId);
}
else
{
UpVotesByThisUser -= 1;
AlreadyUpvoted = false;
IndividualParticipant.getInstance().UpvotedQuestionIDs.Remove(QuestionId);
}
}
else
{
await NavigationUtils.DoRegistrationCheck(
IndividualParticipant.getInstance().ProfileData.RegistrationInfo,
AppResources.NotNowAnswerText);
}
});
QuestionDetailsCommand = new Command(() =>
{
QuestionViewModel.Instance.Question = this;
QuestionViewModel.Instance.IsNewQuestion = false;
_ = Shell.Current.GoToAsync($"{nameof(QuestionDetailPage)}");
});
ShareCommand = new AsyncCommand(async() =>
{
await Share.RequestAsync(new ShareTextRequest
{
Text = QuestionText,
Title = "Share Text"
});
});
ReportCommand = new Command(() =>
{
AlreadyReported = !AlreadyReported;
if (AlreadyReported)
{
IndividualParticipant.getInstance().ReportedQuestionIDs.Add(QuestionId);
}
else
{
IndividualParticipant.getInstance().ReportedQuestionIDs.Remove(QuestionId);
}
});
}

// For questions we read off the server - check whether we've previously up-voted them or
// reported them.
public Question(in QuestionResponseRecords questionResponses) : base()
{
}

// commands
public Command UpvoteCommand { get; }
public Command ReportCommand { get; }
public Command QuestionDetailsCommand { get; }
public IAsyncCommand ShareCommand { get; }

// Call empty constructor to initialize commands etc.
// Then convert data downloaded from server into a displayable form.
public Question(QuestionReceiveFromServer serverQuestion) : this()
public Question(QuestionReceiveFromServer serverQuestion, QuestionResponseRecords questionResponses)
{

// question-defining fields
QuestionSuggester = serverQuestion.author ?? "";
QuestionText = serverQuestion.question_text ?? "";
Expand All @@ -301,6 +215,10 @@ public Question(QuestionReceiveFromServer serverQuestion) : this()
// question non-defining fields
Background = serverQuestion.background ?? "";

// Check whether the user has already responded to this question.
AlreadyUpvoted = questionResponses.IsAlreadyUpvoted(QuestionId);
AlreadyReported = questionResponses.IsAlreadyReported(QuestionId);

interpretFilters(serverQuestion);

WhoShouldAnswerTheQuestionPermissions = serverQuestion.who_should_answer_the_question_permissions;
Expand Down Expand Up @@ -451,6 +369,16 @@ public void AddAnswer(string answer)
};
}

public void ToggleUpvotedStatus()
{
AlreadyUpvoted = !AlreadyUpvoted;
}

public void ToggleReportStatus()
{
AlreadyReported = !AlreadyReported;
}

//validation
public bool ValidateNewQuestion()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text.Json;
using RightToAskClient.Helpers;
using Xamarin.Forms;

namespace RightToAskClient.Models
{
/*
* Stores information about this user's responses to questions: which ones
* they've up-voted, down-voted, dismissed, flagged.
*/
public class QuestionResponseRecords
{
private HashSet<string> _upvotedQuestionIDs;
private HashSet<string> _downvotedQuestionIDs;
private HashSet<string> _reportedQuestionIDs;
private HashSet<string> _dismissedQuestionIDs;
private bool _isInitialised;

public void Init()
{
if (!_isInitialised)
{
// Retrieve from preferences.
_upvotedQuestionIDs = retrieveHashSetFromPreferences(Constants.UpvotedQuestions);
_downvotedQuestionIDs = retrieveHashSetFromPreferences(Constants.DownvotedQuestions);
_dismissedQuestionIDs = retrieveHashSetFromPreferences(Constants.DismissedQuestions);
_reportedQuestionIDs = retrieveHashSetFromPreferences(Constants.ReportedQuestions);
_isInitialised = true;
}
}


public void AddDownvotedQuestion(string questionID)
{
_downvotedQuestionIDs.Add(questionID);
storeHashSetInPreferences(Constants.DownvotedQuestions, _downvotedQuestionIDs);
}

public bool IsAlreadyDownvoted(string questionID) => _downvotedQuestionIDs.Contains(questionID);

public void AddUpvotedQuestion(string questionID)
{
_upvotedQuestionIDs.Add(questionID);
storeHashSetInPreferences(Constants.UpvotedQuestions, _upvotedQuestionIDs);
}

public bool IsAlreadyUpvoted(string questionID) => _upvotedQuestionIDs.Contains(questionID);

public void AddReportedQuestion(string questionID)
{
_reportedQuestionIDs.Add(questionID);
storeHashSetInPreferences(Constants.ReportedQuestions, _reportedQuestionIDs);
}

public bool IsAlreadyReported(string questionID) => _reportedQuestionIDs.Contains(questionID);

public void AddDismissedQuestion(string questionID)
{
_dismissedQuestionIDs.Add(questionID);
storeHashSetInPreferences(Constants.DismissedQuestions, _dismissedQuestionIDs);
}

public bool IsAlreadyDismissed(string questionID) => _dismissedQuestionIDs.Contains(questionID);

private void storeHashSetInPreferences(string key, HashSet<string> hashSet)
{
try
{
var hashSetString = JsonSerializer.Serialize(hashSet);
XamarinPreferences.shared.Set(key, hashSetString);
}
catch (Exception e)
{
Debug.WriteLine("Error storing "+key+" to preferences: "+e.Message);
}
}
private HashSet<string> retrieveHashSetFromPreferences(string key)
{
var retrievedSet = new HashSet<string>();

var retrievedString = XamarinPreferences.shared.Get(key, "");
if (!String.IsNullOrEmpty(retrievedString))
{
try
{
retrievedSet = JsonSerializer.Deserialize<HashSet<string>>(retrievedString);
}
catch (Exception e)
{
Debug.WriteLine("Error deserialising "+key+":"+e.Message);
}
}

return retrievedSet ?? new HashSet<string>();;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Text.Json.Serialization;

namespace RightToAskClient.Models.ServerCommsData
{
public class PlainTextVoteOnQuestionCommand
{

[JsonPropertyName("question_id")]
public string question_id { get; set; }

[JsonPropertyName("up")]
public bool up { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Text.Json.Serialization;

namespace RightToAskClient.Models.ServerCommsData
{
public class PlaintextVoteOnQuestionCommandPostedToBulletinBoard
{
[JsonPropertyName("command")]
public ClientSignedUnparsed command { get; set; }


}
}
Loading

0 comments on commit 929b144

Please sign in to comment.