Misc · Asking and learning: a poll, a survey, a quiz and flashcards
misc::Poll turns to results once the owner holds the vote, with Change vote on Vote's stop. misc::Survey asks on one page and sends when each question is answered, thanking in Submit's place and focus. misc::Quiz checks, goes on, scores and starts again on one button. misc::Flashcards turn on a press and go round the deck, each face fading in. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
19a5295ed8
commit
6e02a0cce3
11 files changed
+1345
-3
No files matched your search
@@ -0,0 +1,120 @@
|
||||
use ely_gpui_component::misc::{Flashcards, Poll, Question, Quiz, QuizQuestion, Survey};
|
||||
use gpui::{App, IntoElement, ParentElement, Styled, Window, div, px};
|
||||
|
||||
use crate::probe::probe;
|
||||
use crate::ui::{section, specimen, specimens};
|
||||
|
||||
/// The gallery's poll: each option's count, and this viewer's vote.
|
||||
struct Tally {
|
||||
votes: [u64; 3],
|
||||
voted: Option<usize>,
|
||||
}
|
||||
|
||||
pub fn render(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
|
||||
let tally = window.use_keyed_state("poll-tally", cx, |_, _| Tally {
|
||||
votes: [14, 9, 5],
|
||||
voted: None,
|
||||
});
|
||||
let (votes, voted) = (tally.read(cx).votes, tally.read(cx).voted);
|
||||
let poll = Poll::new(
|
||||
"poll",
|
||||
"Which chart should come next?",
|
||||
["Sankey", "Sunburst", "Candlestick"],
|
||||
)
|
||||
.votes(votes)
|
||||
.on_vote(move |vote, _, cx| {
|
||||
tally.update(cx, |tally, cx| {
|
||||
match (vote, tally.voted) {
|
||||
(Some(ix), _) => tally.votes[ix] += 1,
|
||||
(None, Some(ix)) => tally.votes[ix] -= 1,
|
||||
(None, None) => panic!("gallery poll: no vote to take back"),
|
||||
}
|
||||
tally.voted = vote;
|
||||
cx.notify();
|
||||
})
|
||||
});
|
||||
let poll = match voted {
|
||||
Some(ix) => poll.voted(ix),
|
||||
None => poll,
|
||||
};
|
||||
div()
|
||||
.child(
|
||||
section(
|
||||
"Poll / Survey",
|
||||
"A poll turns to results once the owner holds the vote, with Change vote on the same stop. A survey asks on one page and sends when every question has its answer.",
|
||||
cx,
|
||||
)
|
||||
.child(
|
||||
specimens()
|
||||
.child(specimen("poll", probe("poll", div().w(px(280.0)).child(poll)), cx))
|
||||
.child(specimen(
|
||||
"survey",
|
||||
div().w(px(320.0)).child(
|
||||
Survey::new(
|
||||
"survey",
|
||||
[
|
||||
Question::Choice(
|
||||
"How often do you ship?".into(),
|
||||
vec!["Daily".into(), "Weekly".into(), "Monthly".into()],
|
||||
),
|
||||
Question::Several(
|
||||
"Which parts do you use?".into(),
|
||||
vec!["Forms".into(), "Charts".into(), "Tables".into()],
|
||||
),
|
||||
Question::Text("What should we build next?".into()),
|
||||
],
|
||||
)
|
||||
.on_submit(|answers, _, _| log::info!("gallery: survey {answers:?}")),
|
||||
),
|
||||
cx,
|
||||
)),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
section(
|
||||
"Quiz / Flashcard",
|
||||
"A quiz checks each answer and shows the right one, then the score. Flashcards turn on a press and go round the deck.",
|
||||
cx,
|
||||
)
|
||||
.child(
|
||||
specimens()
|
||||
.child(specimen(
|
||||
"quiz",
|
||||
probe(
|
||||
"quiz",
|
||||
div().w(px(280.0)).child(Quiz::new(
|
||||
"quiz",
|
||||
[
|
||||
QuizQuestion::new(
|
||||
"Which planet is the largest?",
|
||||
["Mars", "Jupiter", "Venus"],
|
||||
1,
|
||||
),
|
||||
QuizQuestion::new(
|
||||
"How many sides has a hexagon?",
|
||||
["Five", "Six", "Eight"],
|
||||
1,
|
||||
),
|
||||
],
|
||||
)),
|
||||
),
|
||||
cx,
|
||||
))
|
||||
.child(specimen(
|
||||
"flashcards",
|
||||
probe(
|
||||
"flashcards",
|
||||
div().w(px(280.0)).child(Flashcards::new(
|
||||
"flashcards",
|
||||
[
|
||||
("Hola", "Hello"),
|
||||
("Gracias", "Thank you"),
|
||||
("Buenos días", "Good morning"),
|
||||
],
|
||||
)),
|
||||
),
|
||||
cx,
|
||||
)),
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -7,13 +7,14 @@ use crate::probe::probe;
|
||||
use crate::script::Step;
|
||||
use crate::ui::{section, specimen, specimens};
|
||||
|
||||
mod asking;
|
||||
mod codes;
|
||||
|
||||
pub const PAGE: Page = Page {
|
||||
number: 42,
|
||||
slug: "misc",
|
||||
title: "Misc",
|
||||
summary: "Small tools that stand alone: clocks, a stopwatch, a calculator, a unit converter, a QR code scanner, a captcha.",
|
||||
summary: "Small tools that stand alone: clocks, a stopwatch, a calculator, a unit converter, a QR code scanner, a captcha, a poll, a survey, a quiz, flashcards.",
|
||||
render,
|
||||
script: &[
|
||||
Step::DownAt("stopwatch-start", 30.0, 62.0),
|
||||
@@ -42,6 +43,19 @@ pub const PAGE: Page = Page {
|
||||
Step::Type("w7xk"),
|
||||
Step::Key("enter"),
|
||||
Step::Shot("captcha-passed"),
|
||||
Step::DownAt("poll", 50.0, 70.0),
|
||||
Step::UpAt("poll", 50.0, 70.0),
|
||||
Step::DownAt("poll", 27.0, 135.0),
|
||||
Step::UpAt("poll", 27.0, 135.0),
|
||||
Step::Shot("poll-voted"),
|
||||
Step::DownAt("quiz", 45.0, 103.0),
|
||||
Step::UpAt("quiz", 45.0, 103.0),
|
||||
Step::DownAt("quiz", 33.0, 168.0),
|
||||
Step::UpAt("quiz", 33.0, 168.0),
|
||||
Step::Shot("quiz-checked"),
|
||||
Step::DownAt("flashcards", 140.0, 80.0),
|
||||
Step::UpAt("flashcards", 140.0, 80.0),
|
||||
Step::Shot("flashcard-turned"),
|
||||
],
|
||||
};
|
||||
|
||||
@@ -56,6 +70,7 @@ fn render(window: &mut Window, cx: &mut App) -> AnyElement {
|
||||
.child(calculator(cx))
|
||||
.child(converter(cx))
|
||||
.child(codes::render(window, cx))
|
||||
.child(asking::render(window, cx))
|
||||
.into_any_element()
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user