Skip to content

Commit

Permalink
Support Warhammer app text imports (#1394)
Browse files Browse the repository at this point in the history
* Update deps

* Add sample/tests

* Add cleanWarhammerAppText

* Add another test army

* First stab at UI element

* First shot at it working!

* Improved import (send to s3 on error, log to GA)

* Add app_banner

* Update Subscribe.tsx

* Update .prettierrc
  • Loading branch information
daviseford authored Sep 18, 2021
1 parent f9d3776 commit bcd1846
Show file tree
Hide file tree
Showing 22 changed files with 1,633 additions and 83 deletions.
1 change: 0 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"arrowParens": "avoid",
"endOfLine": "auto",
"jsxBracketSameLine": false,
"parser": "typescript",
"printWidth": 110,
"semi": false,
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,10 @@ Obviously, this does not work in production :)

### Warscroll Builder/Azyr/Battlescribe Import

Found a discrepancy between Warscroll Builder/Azyr/Battlescribe and AoS Reminders? You have three options:
Found a discrepancy between Warscroll Builder/Azyr/Battlescribe/Warhammer App and AoS Reminders? You have three options:

1. [Open an issue on Github](https://github.com/daviseford/aos-reminders/issues) and let us know.
2. Add to the typo list (`[warscroll|azyr|battlescribe]TypoMap`) in `src/utils/import/options.ts`
2. Add to the typo list (`[warscroll|azyr|battlescribe|warhammerApp]TypoMap`) in `src/utils/import/options.ts`
3. Just wait. :) Failed imports are fired off to Google Analytics - we will probably fix your issue within a couple days.


Expand Down
22 changes: 11 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "aos-reminders",
"version": "5.0.9",
"version": "5.1.0",
"private": true,
"homepage": "./",
"dependencies": {
Expand All @@ -23,7 +23,7 @@
"react-bootstrap": "1.6.3",
"react-copy-to-clipboard": "5.0.4",
"react-dom": "17.0.2",
"react-dropzone": "11.3.4",
"react-dropzone": "11.4.0",
"react-ga": "3.3.0",
"react-icons": "4.2.0",
"react-modal": "3.14.3",
Expand Down Expand Up @@ -82,25 +82,25 @@
"devDependencies": {
"@types/jest": "26.0.23",
"@types/jspdf": "1.3.3",
"@types/lodash": "4.14.172",
"@types/luxon": "2.0.3",
"@types/node": "16.9.1",
"@types/lodash": "4.14.173",
"@types/luxon": "2.0.4",
"@types/node": "16.9.2",
"@types/parse5": "6.0.1",
"@types/pdfjs-dist": "2.7.1",
"@types/qs": "6.9.7",
"@types/react": "17.0.20",
"@types/react": "17.0.21",
"@types/react-beautiful-dnd": "13.1.2",
"@types/react-copy-to-clipboard": "5.0.1",
"@types/react-dom": "17.0.9",
"@types/react-modal": "3.12.1",
"@types/react-redux": "7.1.18",
"@types/react-router-dom": "5.1.8",
"@types/react-router-dom": "5.1.9",
"@types/react-select": "4.0.17",
"@types/superagent": "4.1.12",
"@types/superagent": "4.1.13",
"@types/webpack-env": "1.16.2",
"babel-jest": "26.6.3",
"husky": "4.3.8",
"prettier": "2.4.0",
"prettier": "2.4.1",
"prettier-plugin-organize-imports": "2.3.3",
"pretty-quick": "3.1.1",
"react-app-rewired": "2.1.8",
Expand All @@ -109,11 +109,11 @@
"ts-node-dev": "1.1.8",
"tsconfig-paths": "3.11.0",
"typescript": "4.3.5",
"workbox-core": "6.2.4",
"workbox-core": "6.3.0",
"workbox-expiration": "6.3.0",
"workbox-precaching": "6.3.0",
"workbox-routing": "6.3.0",
"workbox-strategies": "6.3.0",
"xlsx": "0.17.1"
"xlsx": "0.17.2"
}
}
12 changes: 10 additions & 2 deletions src/components/info/banners/app_banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import React from 'react'

const AppBanner = () => {
const { isDark } = useTheme()
const name = 'aos-3-dominion-update'
const name = 'aos-3-new-warhammer-app-import'

return (
<NotificationBanner
Expand All @@ -14,7 +14,15 @@ const AppBanner = () => {
persistClose={true}
variant={isDark ? `info` : `info`}
>
<span>We've added the latest August FAQs {':)'}</span>
<span>
<strong>NEW: </strong>We've added the ability to import lists from the new Warhammer App. Just hit
"Import List" and then copy + paste your list to get started!
<br />
<small>
This feature is still in development and may change rapidly! Please let me know if you encounter
issues.
</small>
</span>
</NotificationBanner>
)
}
Expand Down
12 changes: 10 additions & 2 deletions src/components/input/importPdf/drop_container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { logClick } from 'utils/analytics'
import { GITHUB_URL, ROUTES } from 'utils/env'
import { hasFatalError } from 'utils/import/warnings'
import { addArmyToStore } from 'utils/loadArmy/loadArmyHelpers'
import { ImportTextarea } from './textarea'

const ImportContainer = () => {
const [errors, setErrors] = useState<IImportedArmy['errors']>([])
Expand All @@ -30,8 +31,15 @@ const ImportContainer = () => {
return (
<>
<div className="row my-2 d-flex justify-content-center">
<div className={'col-12 col-lg-6 col-xl-6 border border-secondary px-0'}>
<ImportDropzone handleDrop={handleDrop} />
<div className={'col-12 col-lg-9 col-xl-9 px-1'}>
<div className="row my-2 d-flex justify-content-center align-content-center">
<div className={'col-12 col-lg-6'}>
<ImportDropzone handleDrop={handleDrop} />
</div>
<div className={'col-12 col-lg-6 pt-2 pt-lg-0'}>
<ImportTextarea handleDrop={handleDrop} />
</div>
</div>
</div>
</div>

Expand Down
77 changes: 77 additions & 0 deletions src/components/input/importPdf/textarea.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { PreferenceApi } from 'api/preferenceApi'
import GenericButton from 'components/input/generic_button'
import { useAppStatus } from 'context/useAppStatus'
import React, { useState } from 'react'
import { IImportedArmy, TXT_FILE, WARHAMMER_APP } from 'types/import'
import { logEvent } from 'utils/analytics'
import { isValidFactionName } from 'utils/armyUtils'
import { hasErrorOrWarning } from 'utils/import/warnings'
import { getWarhammerAppArmy } from 'utils/warhammer_app/getWarhammerAppArmy'
import { cleanWarhammerAppText } from 'utils/warhammer_app/warhammerAppUtils'

const BADGE_CLASS = `badge badge-pill badge-`

interface IImportTextAreaProps {
handleDrop: (army: IImportedArmy) => void
}

export const ImportTextarea: React.FC<IImportTextAreaProps> = ({ handleDrop }) => {
const { isOnline } = useAppStatus()
const [text, setText] = useState('')

const handleImport = () => {
// parse the text and then send it back as an army
const cleanedText = cleanWarhammerAppText(text)
const army = getWarhammerAppArmy(cleanedText)

if (isOnline && hasErrorOrWarning(army.errors)) {
const payload = {
fileTxt: text,
parser: WARHAMMER_APP,
fileType: TXT_FILE,
}
Promise.resolve(PreferenceApi.createErrorFile(payload))
}

if (isOnline && isValidFactionName(army.factionName)) {
logEvent(`Import${WARHAMMER_APP}-${army.factionName}`)
}

return handleDrop(army)
}

return (
<>
<div className="row">
<div className="col-12">
<div className="form-group">
<textarea
name="ImportTextarea"
id="ImportTextarea"
className={'ImportTextarea'}
placeholder={'Or paste your Warhammer App list here'}
onChange={e => {
e.preventDefault()
setText(e.target.value)
}}
value={text}
/>
</div>
</div>
{text && (
<div className="col-12 pb-3 ml-3">
<div className="btn-group" role="group">
<GenericButton className={`${BADGE_CLASS}success mr-1`} type="button" onClick={handleImport}>
Import
</GenericButton>

<GenericButton className={`${BADGE_CLASS}danger mr-1`} onClick={() => setText('')}>
Clear
</GenericButton>
</div>
</div>
)}
</div>
</>
)
}
6 changes: 3 additions & 3 deletions src/components/routes/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import React, { lazy, Suspense, useEffect } from 'react'
import { logPageView } from 'utils/analytics'

const AlliedArmies = lazy(() => import('components/input/ally_armies'))
// const AppBanner = lazy(() => import('components/info/banners/app_banner'))
const AppBanner = lazy(() => import('components/info/banners/app_banner'))
const ArmyBuilder = lazy(() => import('components/input/army_builder'))
const FooterComponent = lazy(() => import('components/page/footer'))
const LoadedArmyHeader = lazy(() => import('components/input/savedArmies/loaded_army_header'))
Expand All @@ -34,9 +34,9 @@ const Home = () => {
<div className={theme.bgColor}>
<Header />

{/* <Suspense fallback={<></>}>
<Suspense fallback={<></>}>
<AppBanner />
</Suspense> */}
</Suspense>

<Suspense fallback={<></>}>
<UpdateBanner />
Expand Down
5 changes: 3 additions & 2 deletions src/components/routes/Subscribe.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,9 @@ const CurrentFeatures = () => (
</p>
<ul className="lead">
<li>
<strong>NEW:</strong> Write, edit, and save notes!
<strong>NEW:</strong> Import lists from the new Warhammer App!
</li>
<li>Write, edit, and save notes!</li>
<li>
Access to <Link to={ROUTES.STATS}>advanced stats!</Link>
</li>
Expand All @@ -167,7 +168,7 @@ const CurrentFeatures = () => (
device - even <strong>offline!</strong>
</li>
<li>
Import your army lists <strong>instantly</strong> from Azyr, Warscroll Builder, and Battlescribe
Import your army lists <strong>instantly</strong> from Azyr, Warscroll Builder, and Battlescribe.
</li>
</ul>
</div>
Expand Down
9 changes: 9 additions & 0 deletions src/css/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,15 @@ small {
margin-block-start: 2px;
}

.ImportTextarea {
min-width: 45%;
width: 100%;
height: 7.5em;
resize: none;
padding: 8px;
box-sizing: border-box;
}

.NoteInput {
min-width: 45%;
width: 95%;
Expand Down
60 changes: 60 additions & 0 deletions src/tests/fixtures/warhammer_app/Fyreslayers1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
Army Name: Fyreslayers1
Army Notes: Some notes go here
Army Faction: Fyreslayers
Subfaction: Greyfyrd
Battlepack: Pitched Battles
Points Limit: 2000 pts
General: Auric Runefather

Units
Auric Runefather (General)
Battlefield Role: Leader
Enhancements
Command Traits: Destroyer of Foes
Artefacts of Power: Helm of Obsidia
Points Cost: 100 pts
Bundo Whalebiter (Ally)
Battlefield Role: Battleline, Behemoth, Leader
Points Cost: 490 pts
Fjul-Grimnir
Battlefield Role: Leader
Points Cost: 150 pts
Auric Runemaster
Battlefield Role: Leader
Points Cost: 115 pts
Auric Runesmiter
Battlefield Role: Leader
Enhancements
Artefacts of Power: Ancestor Helm
Prayers: Prayer Of Ash
Points Cost: 120 pts
Auric Runesmiter on Magmadroth
Battlefield Role: Behemoth, Leader
Points Cost: 275 pts
Auric Runeson
Battlefield Role: Leader
Enhancements
Artefacts of Power: Helm of Obsidia
Points Cost: 90 pts
Auric Runeson on Magmadroth
Battlefield Role: Behemoth, Leader
Points Cost: 240 pts
Battlesmith
Battlefield Role: Leader
Enhancements
Artefacts of Power: Draught of Magmalt Ale
Points Cost: 125 pts
Fjul-Grimnir
Battlefield Role: Leader
Points Cost: 150 pts
Warden King (Ally)
Battlefield Role: Leader
Points Cost: 100 pts

Core Battalions
Alpha-Beast Pack
Alpha-Beast Pack
Battle Regiment

Total Points: 1805 pts
Invalid: Created with Warhammer Age of Sigmar: The App
Loading

0 comments on commit bcd1846

Please sign in to comment.