diff --git a/.github/workflows/publish-to-dockerhub.yml b/.github/workflows/publish-to-dockerhub.yml index c91a578..27ce676 100644 --- a/.github/workflows/publish-to-dockerhub.yml +++ b/.github/workflows/publish-to-dockerhub.yml @@ -24,7 +24,7 @@ jobs: path: "public/manifest.json" prop_path: "version" - name: Update manifest.json version from ${{ steps.manifestversion.outputs.prop }} to ${{ github.ref_name }} - if: ${{ steps.manifestversion.outputs.prop }} != ${{ github.ref_name }} + if: ${{ steps.manifestversion.outputs.prop != github.ref_name }} uses: jossef/action-set-json-field@v2 with: file: public/manifest.json @@ -44,6 +44,7 @@ jobs: tags: "latest, ${{ github.ref_name }}" - name: Create PR with version changes + id: cpr uses: peter-evans/create-pull-request@v4 with: token: ${{ secrets.PAT_PR }} @@ -52,6 +53,7 @@ jobs: body: | Update latest version (${{ github.ref_name }}) branch: update-version-${{ github.ref_name }} + delete-branch: true base: main add-paths: | package.json @@ -60,3 +62,10 @@ jobs: update assignees: | ${{ github.actor }} + - name: Enable Pull Request Automerge + if: steps.cpr.outputs.pull-request-operation == 'created' + uses: peter-evans/enable-pull-request-automerge@v2 + with: + token: ${{ secrets.PAT }} + pull-request-number: ${{ steps.cpr.outputs.pull-request-number }} + merge-method: squash diff --git a/package.json b/package.json index 0987ae8..0a351f3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "frontend", - "version": "5.4.8", + "version": "5.5.0", "description": "React frontend for the Cards 110", "author": "Daithi Hearn", "license": "MIT", diff --git a/public/manifest.json b/public/manifest.json index fb34480..17ac17f 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -1,7 +1,7 @@ { "short_name": "Cards 110", "name": "Cards 110", - "version": "5.4.8", + "version": "5.5.0", "icons": [ { "src": "./assets/favicon.png", diff --git a/src/assets/img/dummy.png b/src/assets/img/dummy.png new file mode 100644 index 0000000..3db7d36 Binary files /dev/null and b/src/assets/img/dummy.png differ diff --git a/src/assets/img/mycards.png b/src/assets/img/mycards.png new file mode 100644 index 0000000..af734b5 Binary files /dev/null and b/src/assets/img/mycards.png differ diff --git a/src/components/Game/Buying.tsx b/src/components/Game/Buying.tsx index 8782b2a..47b4cc8 100644 --- a/src/components/Game/Buying.tsx +++ b/src/components/Game/Buying.tsx @@ -77,13 +77,11 @@ const Buying = () => { ) : null} diff --git a/src/components/Game/GameWrapper.tsx b/src/components/Game/GameWrapper.tsx index 9fb8ed2..60cd8b7 100644 --- a/src/components/Game/GameWrapper.tsx +++ b/src/components/Game/GameWrapper.tsx @@ -23,7 +23,7 @@ const GameWrapper = () => { - + {!iamSpectator ? : null} diff --git a/src/components/Game/MyCards.tsx b/src/components/Game/MyCards.tsx index 28e7e78..3da7a5b 100644 --- a/src/components/Game/MyCards.tsx +++ b/src/components/Game/MyCards.tsx @@ -34,6 +34,14 @@ import { } from "../../caches/AutoPlaySlice" import parseError from "../../utils/ErrorUtils" +const EMPTY_HAND = [ + { ...BLANK_CARD, selected: false }, + { ...BLANK_CARD, selected: false }, + { ...BLANK_CARD, selected: false }, + { ...BLANK_CARD, selected: false }, + { ...BLANK_CARD, selected: false }, +] + const MyCards: React.FC = () => { const dispatch = useAppDispatch() const gameId = useAppSelector(getGameId) @@ -220,61 +228,61 @@ const MyCards: React.FC = () => { - {showDummy && ( - - - - {provided => ( -
- {myCards.slice(5, 10).map((card, index) => { - const draggableId = `${card.name}${ - card.name === BLANK_CARD.name - ? index - : "" - }` - return ( - - {provided => ( -
- - handleSelectCard( - card, - event, - ) - } - src={`/cards/thumbnails/${card.name}.png`} - className={getStyleForCard( + + + + {provided => ( +
+ {(showDummy + ? myCards.slice(5, 10) + : EMPTY_HAND + ).map((card, index) => { + const draggableId = `${card.name}${ + card.name === BLANK_CARD.name + ? index + : "" + }` + return ( + + {provided => ( +
+ + handleSelectCard( card, - )} - /> -
- )} -
- ) - })} - {provided.placeholder} -
- )} -
-
-
- )} + event, + ) + } + src={`/cards/thumbnails/${card.name}.png`} + className={getStyleForCard( + card, + )} + /> +
+ )} +
+ ) + })} + {provided.placeholder} +
+ )} +
+
+
{round?.status === RoundStatus.PLAYING ? ( diff --git a/src/components/Game/SelectSuit.tsx b/src/components/Game/SelectSuit.tsx index a825912..9c19958 100644 --- a/src/components/Game/SelectSuit.tsx +++ b/src/components/Game/SelectSuit.tsx @@ -162,8 +162,8 @@ const SelectSuit = () => { ) : ( - )} diff --git a/src/components/GameStats/WinPercentageGraph.tsx b/src/components/GameStats/WinPercentageGraph.tsx index 62491ab..f89ac04 100644 --- a/src/components/GameStats/WinPercentageGraph.tsx +++ b/src/components/GameStats/WinPercentageGraph.tsx @@ -10,9 +10,18 @@ import StatsService from "../../services/StatsService" interface Props { player: PlayerProfile last3Months: boolean + width?: number + height?: number + showLegend?: boolean } -const WinPercentageGraph: React.FC = ({ player, last3Months }) => { +const WinPercentageGraph: React.FC = ({ + player, + last3Months, + width = 300, + height = 300, + showLegend = true, +}) => { const dispatch = useAppDispatch() const { enqueueSnackbar } = useSnackbar() const [stats, setStats] = useState([]) @@ -46,7 +55,6 @@ const WinPercentageGraph: React.FC = ({ player, last3Months }) => { labels: ["Win", "Loss"], datasets: [ { - label: "My Win Percentage", data: [wins.length, filteredStats.length - wins.length], backgroundColor: ["rgb(54, 162, 235)", "rgb(255, 99, 132)"], hoverOffset: 4, @@ -61,12 +69,15 @@ const WinPercentageGraph: React.FC = ({ player, last3Months }) => { plugins: { title: { display: true, - text: `Win Percentage (${( + text: `${( (wins.length / filteredStats.length) * 100 - ).toFixed(1)}%)`, + ).toFixed(1)}% win rate`, position: "bottom", }, + legend: { + display: showLegend, + }, }, } }, [wins, filteredStats]) @@ -78,8 +89,8 @@ const WinPercentageGraph: React.FC = ({ player, last3Months }) => { ) : ( diff --git a/src/components/MyGames/MyGames.tsx b/src/components/MyGames/MyGames.tsx index 045ea89..7699fe1 100644 --- a/src/components/MyGames/MyGames.tsx +++ b/src/components/MyGames/MyGames.tsx @@ -106,7 +106,7 @@ const MyGames = () => { { name: "Date", selector: row => row.timestamp, - format: row => moment(row.timestamp).format("lll"), + format: row => moment(row.timestamp).format("llll"), sortable: true, }, { diff --git a/src/components/StartNewGame/StartNewGame.tsx b/src/components/StartNewGame/StartNewGame.tsx index a6eee05..68e8fb7 100644 --- a/src/components/StartNewGame/StartNewGame.tsx +++ b/src/components/StartNewGame/StartNewGame.tsx @@ -96,7 +96,7 @@ const StartNewGame = () => { Image Preview @@ -108,9 +108,28 @@ const StartNewGame = () => { sortable: true, }, { - name: "Stats (3 months)", + name: "Last 3 months", cell: (pp: PlayerProfile) => ( - + + ), + center: true, + }, + { + name: "All Time", + cell: (pp: PlayerProfile) => ( + ), center: true, }, diff --git a/src/pages/Game/_game.scss b/src/pages/Game/_game.scss index 8ca023b..bc40c98 100644 --- a/src/pages/Game/_game.scss +++ b/src/pages/Game/_game.scss @@ -8,7 +8,7 @@ } .cardNotSelected { - opacity: 0.9; + opacity: 1; filter: brightness(70%); } @@ -21,6 +21,18 @@ border-width: 5px; border-radius: 10px; padding: 2px; + background-image: url("/assets/img/mycards.png"); +} + +.dummy { + background-image: url("/assets/img/dummy.png"); +} + +.gameContainer { + border-style: solid; + border-width: 5px; + border-radius: 10px; + padding: 2px; } // .carpet { diff --git a/src/pages/Home/_home.scss b/src/pages/Home/_home.scss index 2b99c75..59ccbc9 100644 --- a/src/pages/Home/_home.scss +++ b/src/pages/Home/_home.scss @@ -78,6 +78,13 @@ border-radius: 50%; } +.avatar-large { + vertical-align: middle; + width: 100px; + height: 100px; + border-radius: 50%; +} + .clickable:hover { cursor: pointer; } diff --git a/src/utils/FormattingUtils.ts b/src/utils/FormattingUtils.ts index bcc5404..b99a9fb 100644 --- a/src/utils/FormattingUtils.ts +++ b/src/utils/FormattingUtils.ts @@ -1,3 +1,5 @@ +const MAX_LENGTH = 20 + export const FormatName = (name: string) => name .split("@")[0] @@ -9,3 +11,4 @@ export const FormatName = (name: string) => word.slice(1).toLocaleLowerCase(), ) .join(" ") + .substring(0, MAX_LENGTH)