alopezlago / modaq Goto Github PK
View Code? Open in Web Editor NEWWeb application for assisting moderators with reading and scorekeeping quiz bowl matches.
Home Page: https://www.quizbowlreader.com/demo.html
License: MIT License
Web application for assisting moderators with reading and scorekeeping quiz bowl matches.
Home Page: https://www.quizbowlreader.com/demo.html
License: MIT License
If the user added a URL for the Lifsheets room scoresheet, we should remember it when we open the New Game dialog, and we should switch to the Lifsheets pivot.
We might even want to remember the rosters, so that we don't have to click on Load each time.
We should support QBSchema's Packet class as an import for packets. Depending on what the file format is, we may have to add some logic to the JSON-parsing class to distinguish between YAPP-parsed packets and QBSchema packets.
Bonus leadins don't format text with <em> tags, but they should. CALISTO 2020 packet 1 has some examples of this.
Style the "Choose file" button so that it fits in with the rest of the UI. This may require some tricks such as lowering the visibility of the button, or putting a control over it which ignores its own click. UI Fabric may have its own solution for this too.
We should support exporting to QBSchema's Match object. This will be a little involved, since we'll have to integrate other QBSchema concepts in as well (e.g. LineUp), which requires creating all the TypeScript definitions.
Different quiz bowl formats (ACF, NAQT, PACE) have different rules, such as
There are a couple approaches we can take
We should have an option to load a game from an existing set of cycles, i.e. the ones users can download as a JSON file. This is important for recovery cases where the user hits an error that can't be fixed, or if they want to restore the game to make corrections.
This should belong in the New Game menu category. We can make New Game a split menu, with the default button used for bringing up the New Game dailog.
In a sample of 300,000 question events (tossup buzzes, full bonus hearings):
(These are underestimates: not every protest is recorded; some protest data is deleted when questions must be thrown out.)
This is also an argument in favor of decoupling/ungating Protest Tossup from Wrong answer (see the related issue #42).
We should add a menu item under Actions to load more questions in the case that the reader runs out of questions. We can use the same packet parsing logic, and just append the new tossups/bonuses (and add cycles if needed).
Right now we have one entry in production (index), which generates a large bundle for which webpack emits a warning. We should investigate code-splitting, which will generate multiple bundles that we can load concurrently in index.html. Given the size of the packages in the bundle, it would be ideal to split away uifabric into its own module if possible. See here for more information on code splitting.
The code for importing rosters from Lifsheets has a team limit since it doesn't use an unbound range (e.g. C:L). We should use an unbound range so we can get rid of this arbitrary limit.
Lifsheets has a "Dead" column for marking dead tossups (column Q). We should mark a "1" in this column if the tossup is dead, since this is how we can tell that a game is completed if the last question is missed.
If we remove the @ignore attribute from a field in our mobx store, it will not be stored until the value is removed from localStorage. We should store a versioning field somewhere so we can see what version of our schema is being used, and clear or migrate the uiState if the app is using a new version.
Allow one of the following:
The textboxes for URL fields are too narrow, making it hard to see what's in them. They should be wider, but they can't be a fixed width (maybe something in terms of viewport width?)
No penalty buzzes aren't being persisted, because they're missing in the Cycle's deserializer.
The next PR should have a fix for this.
This happens because the power marker isn't counted as a word, so we don't realize we're at the end of the question.
We should have a soft background (yellow?) on words that the user hovers over.
The reader doesn't understand powers yet. Either the parser needs to provide it, or we need to know that (*) means power.
MODAQ should support some integrations with the QuizBowlDiscordScoreTracker bot to improve reading for Discord tournaments. If these were synchronized, readers could simply read and scorekeep without ever switching to Discord, meaning that they only need one window open.
Some things that should be integrated
This integration would require work from both projects, since the bot would need to add websocket APIs to support this, and would need to support MODAQ's ability to jump between questions.
Alternatively, there could be a new bot that more closely matches MODAQ's architecture. It could be greatly simplified and pared down on commands. It wouldn't need to track score, it would only track buzzes.
Add keyboard shortcuts to improve navigation and accessibility. Some improvements would be:
Expected:
Since the player was removed during this cycle, they must not have buzzed in
Actual:
The player's buzz still stands. You can't remove the buzz through the question viewer, you have to do it through the event viewer.
According to this doucment, the way to handle bonuses read in the wrong order is to modify B#. In cases where games don't read every bonus, we should be able to modify B# ourselves. IBonusAnswerEvent tracks which bonus index was read, so we could set B# to bonusIndex + 1
, assuming we haven't run out of bonuses.
The downside is that the guide also suggests adding a comment, and I haven't found any way to add comments through the Sheets API, and it may not be possible without some reverse-engineering.
Instead of requiring the moderator to find the "Export" button, a prompt could automatically appear at the end of a match and ask something like "Do you want to export this match to the scoresheet now?"
This may be a remedy for the mentioned behavior of moderators exporting frequently throughout a match, as they will come to expect the prompt as part of the default flow, and have a better mental model of when data actually gets "saved".
The reader has no understanding of what is an editor's note or note to the moderator. It should make sure that these aren't included in the word count, and that they can't be clicked on as a place to buzz in.
We should support a file-based scoresheet that can also record buzz points. This will be useful for the desktop-only case (#26) where we want it to work even if there's no internet connectivity.
As far as I know, there are no existing file-only spreadsheets that track advanced stats.
Most components pass in some combination of UIState/GameState, which both come from AppState. We should just pass in AppState everywhere for both.
Make bundle names more consistent, so that the bundles with node modules will remain the same and will be cached for longer.
Make the font and font size of the viewer and other controls customizable. This could be a menu item in the GameBar control.
The "Protest Tossup" action is hard to discover, because you have to know that you need to click on the buzz again. There should be a "Protest Tossup" submenu in the Actions menu. It should be a submenu that shows the players who incorrectly buzzed on it. When we click on that player, we should bring up the protest tossup dialog.
Support other scoresheet formats like UCSD Sheets and TJ Sheets, even though those don't track buzzpoint data.
The reader should automatically count how many points could be gained by a protest being resolved. If resolving protests in a teams favor isn't enough to make them win, we should also tell the reader so they don't have to resolve it.
Add support for bouncebacks, which can be set with dropdowns instead of checkboxes. Might need the game format work done to know if we can score more points than the other team received.
The event viewer should be collapsible. This means that we will want the score somewhere more prominent then it is now.
There should be a desktop application backed by something like Electron.Net or Chromely that hosts the reader. This should probably be in a separate repo.
Benefits:
All of the event handlers and much of the business logic are in the same files as the React components. This makes getting test coverage of this logic annoying to do (testing React components requires some more complicated setup). This also means that much of the business logic is located in the same place as the view. If we wanted to test this business logic, we have to export the functions, which feels off, since we won't be able to separate changes in the view from changes to handling business logic.
We should look into doing the following
This would be a large change, and may not be worth the investment.
The protest dialog has a Reason field which can include the answer, but to make sure moderators don't forget to include the answer given, the protest dialog should have an Answer field.
We can modify the protest events to include an answer field, or we could change the format of the reason field to be "answer\nreason".
The wiki says:
Be sure that the round number is correct to make sure you don't overwrite an existing game.
We should automatically detect whether data already exists in the scoresheet before overwriting it. Ask something defensively like "Are you sure you want to overwrite the data in the Round 2 sheet?", or offer an Undo action (but it may not be worthwhile or desirable to have Undo, since it depends on the moderator noticing a problem in the first place).
Besides prompting users when the scoresheet is already filled in, it would be even better to show exactly which rounds already have data (and it may be possible to do so in 1 API call), so that the moderator can compare their expectations to that list, and the round number could be entered by clicking a button instead of typing a numeric input, which is more prone to mistakes.
Round 1: ✔︎ detected data already in scoresheet
Round 2: ✔︎ detected data already in scoresheet
Round 3
Round 4
We are using value and defaultValue in our SpinButton in the export dialog. We should only use value.
This will require storing state on who was originally in the game.
Currently, buzz points are formatted based on which team buzzed in, so the first team's buzz points are always first. In Lifsheets, buzz points must always be sorted numerically, so the first team's buzz point could appear second.
Repro:
MobX 5 is no longer supported. MobX 6 requires changes in classes to use the makeObservable
or makeAutoObservable
method. See more details here.
When we start a new game, or load the UI state from the application store, we should update the website's title to include the packet name. This will require storing the filename in UIState, since we don't have that information when we create the new game (doing it when we load the packet is too early).
Setting it when we create a new game should be pretty easy. Setting it when we initialize UIState may be harder; this might be something we use mobx.autorun for.
IGameFormat has a separate array for power markers and how many points they are. This should either be an array of tuples, or an array of an interface holding the marker and the number of points. This will prevent any issues where the sizes of the arrays would be different.
The UI is still very bare-bones and has little color in it. We should define themes using UI Fabric's Themes. This means we need to pick a default color scheme, and pass in the theme to more places, perhaps through UIState.
Throwing out the last bonus leads to this error:
Error: TypeError: Cannot read property 'parts' of undefined
Refreshing does not fix this issue. We should show a warning similar to what we show for running out of tossups.
The question viewer doesn't know about pronunciation guides, so readers can click on them to assign buzzes to them, and they are included in the
We should do the following with pronunciation guides:
One challenge is that different packets have different formats for pronunciation guides (braces vs parentheses). This might require completing #17 first.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.