Fix handling of polls (#723)

* Fix handling of polls

* Fixes

---------

Co-authored-by: Thomas Ricouard <ricouard77@gmail.com>
This commit is contained in:
Peter-Josef Meisch 2023-02-09 06:35:19 +01:00 committed by GitHub
parent 11c5da05c2
commit 70dce60b95
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 68 additions and 17 deletions

View file

@ -387,6 +387,7 @@
"status.poll.duration" = "Durada de l'enquesta"; "status.poll.duration" = "Durada de l'enquesta";
"status.poll.frequency" = "Freqüència de l'enquesta"; "status.poll.frequency" = "Freqüència de l'enquesta";
"status.poll.option-n %lld" = "Opció %lld"; "status.poll.option-n %lld" = "Opció %lld";
"status.poll.send" = "Send Vote";
"status.post-from-%@" = "Publicació de: %@"; "status.post-from-%@" = "Publicació de: %@";
"status.row.was-boosted" = "impulsat"; "status.row.was-boosted" = "impulsat";
"status.row.was-reply" = "Ha respost a"; "status.row.was-reply" = "Ha respost a";

View file

@ -388,6 +388,7 @@
"status.poll.duration" = "Umfragedauer"; "status.poll.duration" = "Umfragedauer";
"status.poll.frequency" = "Auswahlmöglichkeiten"; "status.poll.frequency" = "Auswahlmöglichkeiten";
"status.poll.option-n %lld" = "Option %lld"; "status.poll.option-n %lld" = "Option %lld";
"status.poll.send" = "Auswahl absenden";
"status.post-from-%@" = "Beitrag von %@"; "status.post-from-%@" = "Beitrag von %@";
"status.row.was-boosted" = "hat geboostet"; "status.row.was-boosted" = "hat geboostet";
"status.row.was-reply" = "Antwort auf"; "status.row.was-reply" = "Antwort auf";

View file

@ -388,6 +388,7 @@
"status.poll.duration" = "Poll Duration"; "status.poll.duration" = "Poll Duration";
"status.poll.frequency" = "Polling Frequency"; "status.poll.frequency" = "Polling Frequency";
"status.poll.option-n %lld" = "Option %lld"; "status.poll.option-n %lld" = "Option %lld";
"status.poll.send" = "Send Vote";
"status.post-from-%@" = "Post from %@"; "status.post-from-%@" = "Post from %@";
"status.row.was-boosted" = "boosted"; "status.row.was-boosted" = "boosted";
"status.row.was-reply" = "Replied to"; "status.row.was-reply" = "Replied to";

View file

@ -389,6 +389,7 @@
"status.poll.duration" = "Poll Duration"; "status.poll.duration" = "Poll Duration";
"status.poll.frequency" = "Polling Frequency"; "status.poll.frequency" = "Polling Frequency";
"status.poll.option-n %lld" = "Option %lld"; "status.poll.option-n %lld" = "Option %lld";
"status.poll.send" = "Send Vote";
"status.post-from-%@" = "Post from %@"; "status.post-from-%@" = "Post from %@";
"status.row.was-boosted" = "boosted"; "status.row.was-boosted" = "boosted";
"status.row.was-reply" = "Replied to"; "status.row.was-reply" = "Replied to";

View file

@ -389,6 +389,7 @@
"status.poll.duration" = "Duración de la encuesta"; "status.poll.duration" = "Duración de la encuesta";
"status.poll.frequency" = "Frecuencia de la encuesta"; "status.poll.frequency" = "Frecuencia de la encuesta";
"status.poll.option-n %lld" = "Opción %lld"; "status.poll.option-n %lld" = "Opción %lld";
"status.poll.send" = "Send Vote";
"status.post-from-%@" = "Publicado por %@"; "status.post-from-%@" = "Publicado por %@";
"status.row.was-boosted" = "retooteó"; "status.row.was-boosted" = "retooteó";
"status.row.was-reply" = "Respuesta a"; "status.row.was-reply" = "Respuesta a";

View file

@ -384,6 +384,7 @@
"status.poll.duration" = "Durée du sondage"; "status.poll.duration" = "Durée du sondage";
"status.poll.frequency" = "Fréquence de sondage"; "status.poll.frequency" = "Fréquence de sondage";
"status.poll.option-n %lld" = "Option %lld"; "status.poll.option-n %lld" = "Option %lld";
"status.poll.send" = "Send Vote";
"status.post-from-%@" = "Publication de %@"; "status.post-from-%@" = "Publication de %@";
"status.row.was-boosted" = "a boosté"; "status.row.was-boosted" = "a boosté";
"status.row.was-reply" = "Répondu à"; "status.row.was-reply" = "Répondu à";

View file

@ -389,6 +389,7 @@
"status.poll.duration" = "Durata del sondaggio"; "status.poll.duration" = "Durata del sondaggio";
"status.poll.frequency" = "Frequenza di voto"; "status.poll.frequency" = "Frequenza di voto";
"status.poll.option-n %lld" = "Opzione %lld"; "status.poll.option-n %lld" = "Opzione %lld";
"status.poll.send" = "Send Vote";
"status.post-from-%@" = "Post da %@"; "status.post-from-%@" = "Post da %@";
"status.row.was-boosted" = "ha condiviso"; "status.row.was-boosted" = "ha condiviso";
"status.row.was-reply" = "Risposta per"; "status.row.was-reply" = "Risposta per";

View file

@ -389,6 +389,7 @@
"status.poll.frequency" = "投票頻度"; "status.poll.frequency" = "投票頻度";
"status.poll.option-n %lld" = "オプション %lld"; "status.poll.option-n %lld" = "オプション %lld";
"status.post-from-%@" = "%@ の投稿"; "status.post-from-%@" = "%@ の投稿";
"status.poll.send" = "Send Vote";
"status.row.was-boosted" = "ブーストした"; "status.row.was-boosted" = "ブーストした";
"status.row.was-reply" = "返信"; "status.row.was-reply" = "返信";
"status.row.you-boosted" = "ブーストしました"; "status.row.you-boosted" = "ブーストしました";

View file

@ -390,6 +390,7 @@
"status.poll.duration" = "투표 기간"; "status.poll.duration" = "투표 기간";
"status.poll.frequency" = "투표 선택 옵션"; "status.poll.frequency" = "투표 선택 옵션";
"status.poll.option-n %lld" = "선택지 %lld"; "status.poll.option-n %lld" = "선택지 %lld";
"status.poll.send" = "Send Vote";
"status.post-from-%@" = "%@님의 글"; "status.post-from-%@" = "%@님의 글";
"status.row.was-boosted" = "님이 부스트함"; "status.row.was-boosted" = "님이 부스트함";
"status.row.was-reply" = "댓글:"; "status.row.was-reply" = "댓글:";

View file

@ -388,6 +388,7 @@
"status.poll.duration" = "Avstemningens varighet"; "status.poll.duration" = "Avstemningens varighet";
"status.poll.frequency" = "Avstemningsfrekvens"; "status.poll.frequency" = "Avstemningsfrekvens";
"status.poll.option-n %lld" = "Valg %lld"; "status.poll.option-n %lld" = "Valg %lld";
"status.poll.send" = "Send Vote";
"status.post-from-%@" = "Innlegg fra %@"; "status.post-from-%@" = "Innlegg fra %@";
"status.row.was-boosted" = "forsterket"; "status.row.was-boosted" = "forsterket";
"status.row.was-reply" = "Svar til"; "status.row.was-reply" = "Svar til";

View file

@ -382,6 +382,7 @@
"status.poll.duration" = "Pollduur"; "status.poll.duration" = "Pollduur";
"status.poll.frequency" = "Pollingfrequentie"; "status.poll.frequency" = "Pollingfrequentie";
"status.poll.option-n %lld" = "Optie %lld"; "status.poll.option-n %lld" = "Optie %lld";
"status.poll.send" = "Send Vote";
"status.post-from-%@" = "Post van %@"; "status.post-from-%@" = "Post van %@";
"status.row.was-boosted" = "geboost"; "status.row.was-boosted" = "geboost";
"status.row.was-reply" = "Geantwoord op"; "status.row.was-reply" = "Geantwoord op";

View file

@ -383,6 +383,7 @@
"status.poll.duration" = "Czas trwania sondażu"; "status.poll.duration" = "Czas trwania sondażu";
"status.poll.frequency" = "Częstotliwość odpytywania"; "status.poll.frequency" = "Częstotliwość odpytywania";
"status.poll.option-n %lld" = "Opcja %lld"; "status.poll.option-n %lld" = "Opcja %lld";
"status.poll.send" = "Send Vote";
"status.post-from-%@" = "Post od %@"; "status.post-from-%@" = "Post od %@";
"status.row.was-boosted" = "podbił(a)"; "status.row.was-boosted" = "podbił(a)";
"status.row.was-reply" = "Odpowiedział(a) do"; "status.row.was-reply" = "Odpowiedział(a) do";

View file

@ -388,6 +388,7 @@
"status.poll.duration" = "Duração da votação"; "status.poll.duration" = "Duração da votação";
"status.poll.frequency" = "Frequência da votação"; "status.poll.frequency" = "Frequência da votação";
"status.poll.option-n %lld" = "Opção %lld"; "status.poll.option-n %lld" = "Opção %lld";
"status.poll.send" = "Send Vote";
"status.post-from-%@" = "Postar de %@"; "status.post-from-%@" = "Postar de %@";
"status.row.was-boosted" = "deu boost"; "status.row.was-boosted" = "deu boost";
"status.row.was-reply" = "Respondeu a"; "status.row.was-reply" = "Respondeu a";

View file

@ -384,6 +384,7 @@
"status.poll.duration" = "Anket Süresi"; "status.poll.duration" = "Anket Süresi";
"status.poll.frequency" = "Anket Sıklığı"; "status.poll.frequency" = "Anket Sıklığı";
"status.poll.option-n %lld" = "Seçenek %lld"; "status.poll.option-n %lld" = "Seçenek %lld";
"status.poll.send" = "Send Vote";
"status.post-from-%@" = "Gönderi tarafından %@"; "status.post-from-%@" = "Gönderi tarafından %@";
"status.row.was-boosted" = "yükseltildi"; "status.row.was-boosted" = "yükseltildi";
"status.row.was-reply" = "Şuna cevap verildi"; "status.row.was-reply" = "Şuna cevap verildi";

View file

@ -389,6 +389,7 @@
"status.poll.duration" = "投票持续时间"; "status.poll.duration" = "投票持续时间";
"status.poll.frequency" = "投票频率"; "status.poll.frequency" = "投票频率";
"status.poll.option-n %lld" = "%lld 选项"; "status.poll.option-n %lld" = "%lld 选项";
"status.poll.send" = "Send Vote";
"status.post-from-%@" = "%@ 的嘟文"; "status.post-from-%@" = "%@ 的嘟文";
"status.row.was-boosted" = "转发"; "status.row.was-boosted" = "转发";
"status.row.was-reply" = "回复到"; "status.row.was-reply" = "回复到";

View file

@ -36,18 +36,40 @@ public struct StatusPollView: View {
} }
private func isSelected(option: Poll.Option) -> Bool { private func isSelected(option: Poll.Option) -> Bool {
for vote in viewModel.votes { if let optionIndex = viewModel.poll.options.firstIndex(where: { $0.id == option.id }),
return viewModel.poll.options.firstIndex(where: { $0.id == option.id }) == vote let _ = viewModel.votes.firstIndex(of: optionIndex) {
return true
} }
return false return false
} }
private func buttonImage(option: Poll.Option) -> some View {
let isSelected = isSelected(option: option)
var imageName = ""
if viewModel.poll.multiple {
if isSelected {
imageName = "checkmark.square"
} else {
imageName = "square"
}
} else {
if isSelected {
imageName = "record.circle"
} else {
imageName = "circle"
}
}
return Image(systemName: imageName)
.foregroundColor(theme.labelColor)
}
public var body: some View { public var body: some View {
VStack(alignment: .leading) { VStack(alignment: .leading) {
ForEach(viewModel.poll.options) { option in ForEach(viewModel.poll.options) { option in
HStack { HStack {
makeBarView(for: option) makeBarView(for: option, buttonImage: buttonImage(option: option))
if !viewModel.votes.isEmpty || viewModel.poll.expired || status.account.id == currentAccount.account?.id { .disabled(viewModel.poll.expired || (viewModel.poll.voted ?? false))
if viewModel.showResults || status.account.id == currentAccount.account?.id {
Spacer() Spacer()
Text("\(percentForOption(option: option))%") Text("\(percentForOption(option: option))%")
.font(.scaledSubheadline) .font(.scaledSubheadline)
@ -55,6 +77,16 @@ public struct StatusPollView: View {
} }
} }
} }
if !viewModel.poll.expired, !(viewModel.poll.voted ?? false), !viewModel.votes.isEmpty {
Button("status.poll.send") {
Task {
do {
await viewModel.postVotes()
}
}
}
.buttonStyle(.bordered)
}
footerView footerView
}.onAppear { }.onAppear {
@ -82,18 +114,13 @@ public struct StatusPollView: View {
} }
@ViewBuilder @ViewBuilder
private func makeBarView(for option: Poll.Option) -> some View { private func makeBarView(for option: Poll.Option, buttonImage: some View) -> some View {
let isSelected = isSelected(option: option)
Button { Button {
if !viewModel.poll.expired, if !viewModel.poll.expired,
viewModel.votes.isEmpty,
let index = viewModel.poll.options.firstIndex(where: { $0.id == option.id }) let index = viewModel.poll.options.firstIndex(where: { $0.id == option.id })
{ {
withAnimation { withAnimation {
viewModel.votes.append(index) viewModel.handleSelection(index)
Task {
await viewModel.postVotes()
}
} }
} }
} label: { } label: {
@ -119,12 +146,9 @@ public struct StatusPollView: View {
.clipShape(RoundedRectangle(cornerRadius: 8)) .clipShape(RoundedRectangle(cornerRadius: 8))
HStack { HStack {
if isSelected { buttonImage
Image(systemName: "checkmark.circle.fill")
.foregroundColor(.mint)
}
Text(option.title) Text(option.title)
.foregroundColor(.white) .foregroundColor(theme.labelColor)
.font(.scaledBody) .font(.scaledBody)
.minimumScaleFactor(0.7) .minimumScaleFactor(0.7)
} }

View file

@ -11,7 +11,7 @@ public class StatusPollViewModel: ObservableObject {
@Published var votes: [Int] = [] @Published var votes: [Int] = []
var showResults: Bool { var showResults: Bool {
!votes.isEmpty || poll.expired poll.ownVotes?.isEmpty == false || poll.expired
} }
public init(poll: Poll) { public init(poll: Poll) {
@ -38,4 +38,16 @@ public class StatusPollViewModel: ObservableObject {
print(error) print(error)
} }
} }
public func handleSelection(_ pollIndex: Int) {
if poll.multiple {
if let voterIndex = votes.firstIndex(of: pollIndex) {
votes.remove(at: voterIndex)
} else {
votes.append(pollIndex)
}
} else {
votes = [pollIndex]
}
}
} }