Мне всегда нравились хорошие викторины, будь то Academic Bowl в старшей школе, Jeopardy на диване или HQ Trivia на моем телефоне. Это был просто главный источник вдохновения. Я также хотел создать приложение, которое могло бы иметь широкий круг постоянных пользователей. В моё текущее портфолио в основном входят проекты, которые могут быть полезны для конкретной цели и в лучшем случае будут апеллировать лишь к решению узко поставленной задачи. Идея на этот раз заключалась в том, чтобы создать приложение, которое было бы достаточно простым, чтобы его мог использовать широкий круг пользователей, и которое я мог бы масштабировать дальше, продолжая наращивать свою базу знаний в области программирования. Вот ссылки на front-end репо и back-end репо)

Обзор функций

Игра похожа на HQ Trivia тем, что ее основной особенностью является вопрос с тремя вариантами ответа. Однако мой поворот в игре заключается в том, что вместо того, чтобы получить определенное право в заданном времени, выигрыш основан на том, на сколько вопросов пользователь может ответить правильно подряд, то есть на полосе. Когда пользователь отвечает на вопрос неправильно, счетчик серии обнуляется, и пользователю приходится начинать серию заново со следующего непросмотренного вопроса. Я также реализовал социальную функцию приложения, в которой записывается самая высокая полоса пользователей, и пользователи ранжируются по метрике. Рейтинги отображаются на панели инструментов после входа в систему. Наконец, приложение позволяет пользователю задавать собственные вопросы. Это функция, которая отличает приложение от других приложений для игр и викторин и, что наиболее важно, позволяет приложению расти за счет пользовательского контента (что способствует интерактивности и повышает повторяемость игры).

Настройка фреймворка

Бэкенд — обзор и модели

Базовая настройка серверной части выполняется через Rails v5.2. В приложении есть модели пользователя и вопроса с has_many отношением между первой и второй. Пользователь имеет типичные атрибуты идентификации ( username , password и т. д.), а также атрибуты для отслеживания игровой статистики, включая streak , highest_streak и last_question_answered_id . Они будут рассмотрены более подробно позже, а пока достаточно сказать, что streak используется во время игры и увеличивается, когда пользователь правильно отвечает на вопрос. last_question_answered_id обновляется и сохраняется каждый раз, когда пользователь отвечает на вопрос (правильный или нет), так что пользователь может продолжить с того места, на котором остановился, каждый раз при запуске игры.

Бэкенд — маршруты и контроллеры

Маршруты, насколько это возможно, поддерживают RESTful и вложены в маршрут namespaced api/v1/[resources]. За исключением маршрута для всех вопросов и всех пользователей, которые извлекаются React при загрузке приложения, ресурс questions вложен в users, чтобы отразить отношения has_many, и что ни один вопрос не может быть отредактирован без входа в систему user. два контроллера, как и ожидалось — users_controller и questions_controller как и ожидалось, соответственно.

Аутентификация

Текущая аутентификация очень проста, предоставляется только через bcrypt , гем Ruby. Это реализовано как атрибут user с использованием password_digest и пользовательской модели, имеющей has_secure_password в модели. Наконец, вход и регистрация настраиваются в auth_controller, который, согласно DHH, настраивается как ресурс с помощью методов #show и #create. Эта настройка предоставила базовые функции для первоначального тестирования и сборки приложения. Я ожидаю реализовать аутентификацию JWT в ближайшем будущем, чтобы аутентификация была более надежной.

Ход игры в React (интерфейс)

Я новичок в React, поэтому для меня это была возможность узнать больше, чем что-либо еще. Оглядываясь назад, я думаю, что вникал во все функциональные возможности и действительно оттачивал понимание нюансов основных предложений React. Я настроил приложение с пятью основными компонентами контейнера (включая общий App.js) и пятью презентационными компонентами. Для управления состоянием я использовал Redux, в котором магазин реализовал один основной редюсер (для управления вопросами) и меньший для управления всеми пользователями.

Основной ход игры выглядит следующим образом:

  1. Приложение загружает все вопросы с помощью запроса на выборку, когда App.js загружается в обработчик жизненного цикла componentWillMount и сохраняется в состоянии Redux в виде массива questions. Вопрос сам по себе является объектом со следующими атрибутами: text, first_choice, second_choice, third_choice и correct_answer.
  2. Когда пользователь нажимает «Играть в игру» из навигации, выполняется действие, которое фильтрует вопросы loadGameQuestions, которое фильтрует вопросы, чтобы гарантировать, что будут только вопросы, которые пользователь не видел, и те, которые сам пользователь не отправил. загружен. Это загружается в selectedQuestions, который также существует в базовом состоянии редукции. Состояние редукции выглядит следующим образом:
state = {
   user:{},
   questions: [],
   selectedQuestions: []
 }

3. Затем, когда пользователь нажимает «Играть в игру», selectedQuestions сопоставляется с компонентом через библиотеку connect и функцию mapStateToProps.

4. Когда все вопросы отсортированы и доступны локально, логика заключается в простом переборе массива selectedQuestions, показывающего каждый вопрос в форме, с index (локальная переменная состояния), которая будет увеличиваться на единицу при каждой отправке формы. показано в функции render() компонента PlayGame.

5. На каждой итерации ответ пользователя (хранящийся в локальном состоянии как userAnswer)) оценивается по атрибуту correct_answer вопроса в функции обратного вызова handleOnClick формы с вызовом презентационного компонента в методе render() презентационного компонента Message.js, показывающего сообщение для правильного или неправильного ответа.

Это в значительной степени основной контейнер и связанный с ним презентационный компонент, выполняющий основную часть приложения. Другие контейнеры и связанные с ними презентационные компоненты в основном используются для настройки и не так важны, как выше. Тем не менее, вот краткое изложение.

  • App — это контейнер высшего порядка, загружающий все маршруты и навбар.
  • Контейнер панели инструментов — содержит «лобби» приложения, которое показывает нам ранжирование пользователей по сериям. Дополнительные функции, показывающие статистику пользователя, могут быть здесь.
  • Контейнер рейтингов — содержит все рейтинги с помощью данных из массива ranked_users, заполненного в usersReducer. Рейтинги загружаются в презентационный компонент Рейтинги, показывая каждый по отдельности.
  • Контейнер «Вопросы» — содержит компонент «Форма вопросов», а также презентационный компонент «Вопросы», который показывает каждый отдельный вопрос в формате карточки. QuestionsForm — это функциональный компонент, который загружает форму для ввода пользовательских вопросов.

Навигация и маршрутизация в React

Изначально навигация была абстрактной концепцией, которую нужно было понять. Когда я планировал приложение, я постоянно мучился вопросом: «Где это приложение запускается?» — то есть должна ли информационная панель быть первой, которую видит пользователь? Должен ли пользователь начать с игры, а затем перейти к другим частям сайта? Как лучше всего подойти к пользовательскому интерфейсу в рамках моих знаний и что можно построить?

С этой целью я немного поэкспериментировал, прежде чем перейти к текущей реализации, где пользователь попадает на страницу «О программе», описывает правила игры, а затем может зарегистрироваться/войти и продолжить игру. игра без вопросов.

Реальным способом для этого было использование метода {Link} библиотеки react-router, который связывал каждый маршрут с соответствующими кнопками NavBar, созданными в отдельном компоненте — Navbar.js.

Стайлинг

Одной из самых неприятных вещей при создании приложения, по крайней мере, при работе над функциональными элементами, был внешний вид (или его отсутствие). Очень неприятно видеть функциональный продукт, который выглядит некрасиво! Чтобы сохранить рассудок, я погуглил и нашел Semantic UI, и я глубоко благодарен за его существование. Стиль в целом минималистичный и простой и выглядит профессионально на любом веб-сайте. Хотя я признаю, что это не лучший внешний вид для текущего приложения, которое должно быть немного более шумным и анимированным, поскольку оно должно быть увлекательной игрой, но на данный момент этого достаточно, и я постараюсь реализовать более продвинутый интерфейс. методы укладки в будущем.

Следующие шаги

Оглядываясь на приложение до сих пор, я могу указать на пару вех.

  1. Это функционально! — пользователь, предпочтительно любитель викторин, может играть в игру, зная, что она будет работать без проблем.
  2. Текущие настройки React и Rails — хорошая база, которую можно масштабировать для роста.

Итак, каковы следующие шаги? Что ж, я рассматриваю это как приложение, которое я в конечном итоге разверну на Heroku. С этой целью я планирую 1) улучшить стиль (более оригинальный стиль и анимация), 2) добавить проверки и устранить любые проблемы при отправке форм, а также добавить более высокую аутентификацию, т. е. 3) JWT. Что касается функциональности, я планирую улучшить социальный аспект — возможность добавлять друзей на сайт. Это все на данный момент. Надеюсь, вам понравилось читать о моем первом путешествии в мир React и, в более широком смысле, веб-разработки с полным стеком!