diff --git a/TODO.md b/TODO.md
index d2ab521..a5f6b0a 100644
--- a/TODO.md
+++ b/TODO.md
@@ -31,7 +31,6 @@ For screenshots:
// todo later PR:
-- improve large screen
- Use the hasVisited state to announce
- add some custom daily puzzles
- consolidate control buttons into hamburger menu (and add share button)
@@ -45,3 +44,4 @@ For screenshots:
- just rename dispatch params to dispatcher everywhere
- put arrayToGrid to common or to word-logic package
- piecesOverlapQ should use getGridFromPieces
+- // todo put screenshots of lexlet and blobble and wordfall ()as webp/compressed images? in MoreGames.js
diff --git a/src/components/App.js b/src/components/App.js
index 19161bb..68bd5a1 100644
--- a/src/components/App.js
+++ b/src/components/App.js
@@ -2,10 +2,14 @@ import React from "react";
import Game from "./Game";
import Heart from "./Heart";
import Rules from "./Rules";
+import ExtendedMenu from "./ExtendedMenu";
+import MoreGames from "./MoreGames";
import Stats from "./Stats";
import CustomCreation from "./CustomCreation";
import CustomShare from "./CustomShare";
import ControlBar from "./ControlBar";
+import FallbackInstall from "./FallbackInstall";
+import CustomError from "./CustomError";
import {
handleAppInstalled,
handleBeforeInstallPrompt,
@@ -185,15 +189,7 @@ export default function App() {
return ;
case "heart":
- return (
-
- );
+ return ;
case "settings":
return (
@@ -217,12 +213,12 @@ export default function App() {
dailyDispatchGameState({action: "getHint"})}
>
- setDisplay("game")}>
+ setDisplay("game")}>
Exit daily challenge
@@ -248,7 +244,8 @@ export default function App() {
{
let representativeString;
try {
@@ -269,11 +266,11 @@ export default function App() {
});
setDisplay("game");
}}
- >
- Play
-
+ >
+
{
let representativeString;
try {
@@ -304,11 +301,10 @@ export default function App() {
setDisplay("customShare");
}
}}
- >
- Share
-
+ >
+
setDisplay("game")}>
- Cancel
+ Exit custom creation
- {`Your game isn't ready to share yet: \n\n${customState.invalidReason}`}
- {
- dispatchCustomState({
- action: "updateInvalidReason",
- invalidReason: "",
- });
- setDisplay("custom");
- }}
- >
- Ok
-
-
+
);
case "customShare":
@@ -347,14 +334,27 @@ export default function App() {
>
);
+ case "moreGames":
+ return
;
+
+ case "fallbackInstall":
+ return
;
+
+ case "extendedMenu":
+ return (
+
+ );
+
default:
return (
{
dispatchGameState({
@@ -22,35 +14,17 @@ function ControlBar({
});
}}
>
+
dispatchGameState({action: "getHint"})}
>
- setDisplay("settings")}
- >
- setDisplay("rules")}
- >
- setDisplay("custom")}
- >
- setDisplay("heart")}
- >
+
{dailyIsSolved ? (
{
dispatchGameState({action: "clearStreakIfNeeded"});
@@ -59,22 +33,39 @@ function ControlBar({
>
) : (
setDisplay("daily")}
>
)}
- {showInstallButton && installPromptEvent ? (
+
+ setDisplay("custom")}
+ >
+
+ {navigator.canShare ? (
- handleInstall(installPromptEvent, setInstallPromptEvent)
+ handleShare({
+ appName: "Crossjig",
+ text: "Check out this word game!",
+ url: "https://crossjig.com",
+ })
}
>
) : (
<>>
)}
+
+
);
}
diff --git a/src/components/CustomError.js b/src/components/CustomError.js
new file mode 100644
index 0000000..cc4317a
--- /dev/null
+++ b/src/components/CustomError.js
@@ -0,0 +1,24 @@
+import React from "react";
+
+export default function CustomError({
+ invalidReason,
+ dispatchCustomState,
+ setDisplay,
+}) {
+ return (
+
+
{`Your custom crossjig isn't ready to play yet: \n\n${invalidReason}`}
+
{
+ dispatchCustomState({
+ action: "updateInvalidReason",
+ invalidReason: "",
+ });
+ setDisplay("custom");
+ }}
+ >
+ Ok
+
+
+ );
+}
diff --git a/src/components/ExtendedMenu.js b/src/components/ExtendedMenu.js
new file mode 100644
index 0000000..90b7b17
--- /dev/null
+++ b/src/components/ExtendedMenu.js
@@ -0,0 +1,80 @@
+import React from "react";
+import packageJson from "../../package.json";
+import {handleShare} from "../common/handleShare";
+import {handleInstall} from "../common/handleInstall";
+
+export default function ExtendedMenu({
+ setDisplay,
+ setInstallPromptEvent,
+ showInstallButton,
+ installPromptEvent,
+}) {
+ return (
+
+ );
+}
diff --git a/src/components/FallbackInstall.js b/src/components/FallbackInstall.js
new file mode 100644
index 0000000..f23ad81
--- /dev/null
+++ b/src/components/FallbackInstall.js
@@ -0,0 +1,31 @@
+import React from "react";
+
+export default function FallbackInstall({setDisplay}) {
+ return (
+
+
+
+ Crossjig is a progressive web app, which means that it can be
+ installed on your phone for easy access and offline play.
+
+
+ {
+ "For iOS: Open Crossjig in Safari and select 'add to home screen' (under the Safari 'share' menu)."
+ }
+
+
+ {
+ "For Android: Open Crossjig in Chrome and select 'install' (under the Chrome ⋮ menu)."
+ }
+
+
+ For the most up-to-date instructions, do a web search for how to
+ install a progressive web app for your phone.
+
+
+
setDisplay("game")}>
+ Close
+
+
+ );
+}
diff --git a/src/components/Heart.js b/src/components/Heart.js
index 47decdb..1b0cb98 100644
--- a/src/components/Heart.js
+++ b/src/components/Heart.js
@@ -1,26 +1,9 @@
import React from "react";
-import Share from "./Share";
-export default function Heart({setDisplay, appName, shareText, repoName, url}) {
+export default function Heart({setDisplay, repoName}) {
return (
-
{appName}
- {"Like this game? Share it with your friends.\n\n"}
- {
}
- {`\n`}
- {
}
- {`\n`}
- {`Want more games? Check out `}
-
Lexlet
- {" and "}
-
Blobble
- {" or see all of our puzzle games "}
-
here
- {`. `}
- {`\n\n`}
- {
}
- {`\n`}
{"Feedback? "}
{`.`}
+ {`\n\n`}
{ }
{`\n`}
Privacy policy
diff --git a/src/components/MoreGames.js b/src/components/MoreGames.js
new file mode 100644
index 0000000..d49622c
--- /dev/null
+++ b/src/components/MoreGames.js
@@ -0,0 +1,20 @@
+import React from "react";
+
+export default function MoreGames({setDisplay}) {
+ return (
+
+
+ {`Want more games? Check out `}
+
Lexlet
+ {" and "}
+
Blobble
+ {" or see all of our puzzle games "}
+
here
+ {`. `}
+
+
setDisplay("game")}>
+ Close
+
+
+ );
+}
diff --git a/src/components/Rules.js b/src/components/Rules.js
index eb1ebee..31b7fb8 100644
--- a/src/components/Rules.js
+++ b/src/components/Rules.js
@@ -5,34 +5,37 @@ export default function Rules({setDisplay}) {
return (
-
- Drag the pieces to the board to make words vertically and
- horizontally. All words must connect.
-
-
- Drag a blank space to move the whole puzzle.
-
-
- Long press and drag to move a group of touching pieces.
-
-
- Click the magnifying glass to get a hint. A hint will move all
- pieces that are on the board to their correct location. If all pieces
- are already in the correct location, a new piece will be added to the
- board.
-
-
- Click the gear to change the number of pieces in the puzzle.
-
-
- Click the calendar to play the daily challenge. The daily
- challenge is easiest on Monday and gets harder over the week.
-
-
- Click the pencil to build your own puzzle to share with friends.
-
-
-
+
+
+ Drag the pieces to the board to make words vertically and
+ horizontally. All words must connect.
+
+
+ Drag a blank space to move the whole puzzle.
+
+
+ Long press and drag to move a group of touching pieces.
+
+
+ Click
to get a hint. A
+ hint will move all pieces that are on the board to their correct
+ location. If all pieces are already in the correct location, a new
+ piece will be added to the board.
+
+
+ Click
to change
+ the number of pieces in the puzzle or the validity indication.
+
+
+ Click
to
+ play the daily challenge. The daily challenge is easiest on Monday and
+ gets harder over the week.
+
+
+ Click
to build your
+ own crossjig to share with friends.
+
+
+
+
+
diff --git a/src/images/icons/help.svg b/src/images/icons/hint.svg
similarity index 100%
rename from src/images/icons/help.svg
rename to src/images/icons/hint.svg
diff --git a/src/images/icons/menu.svg b/src/images/icons/menu.svg
new file mode 100644
index 0000000..edf8975
--- /dev/null
+++ b/src/images/icons/menu.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/src/images/icons/more.svg b/src/images/icons/more.svg
new file mode 100644
index 0000000..e81781b
--- /dev/null
+++ b/src/images/icons/more.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/src/images/icons/play.svg b/src/images/icons/play.svg
new file mode 100644
index 0000000..574cb17
--- /dev/null
+++ b/src/images/icons/play.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/src/images/icons/question.svg b/src/images/icons/question.svg
new file mode 100644
index 0000000..e8f844a
--- /dev/null
+++ b/src/images/icons/question.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/src/images/icons/share.svg b/src/images/icons/share.svg
new file mode 100644
index 0000000..bea9b3c
--- /dev/null
+++ b/src/images/icons/share.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/src/styles/App.css b/src/styles/App.css
index d645cad..03c11ba 100644
--- a/src/styles/App.css
+++ b/src/styles/App.css
@@ -337,7 +337,6 @@ body:has(#drag-group) {
font-size: calc(var(--default-font-size) * 0.75);
}
-.customMessage > div,
.customMessage > a {
white-space: pre-line;
text-wrap: wrap;
diff --git a/src/styles/ControlBar.css b/src/styles/ControlBar.css
index 4c201c5..85a82f0 100644
--- a/src/styles/ControlBar.css
+++ b/src/styles/ControlBar.css
@@ -1,3 +1,43 @@
+#extendedMenu {
+ display: flex;
+ flex-direction: column;
+ width: fit-content;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+#extendedMenu > h1 {
+ text-align: center;
+}
+
+#extendedMenu > button {
+ background-color: var(--dark-color);
+ color: var(--light-color);
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: left;
+}
+
+#extendedMenu span {
+ padding: 10px;
+}
+
+.extendedMenuIcon {
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: contain;
+ border: 0;
+ width: var(--default-font-size);
+ height: var(--default-font-size);
+ background-color: transparent;
+ padding: 1px 6px;
+}
+
+#version {
+ text-align: center;
+}
+
#controls {
display: flex;
justify-content: space-evenly;
@@ -19,41 +59,65 @@
padding: 1px 6px;
}
-#settingsButton {
+#settingsIcon {
background-image: url("../images/icons/settings.svg");
}
-#newGameButton {
+#newGameIcon {
background-image: url("../images/icons/new_game.svg");
}
-#helpButton {
- background-image: url("../images/icons/help.svg");
+#hintIcon {
+ background-image: url("../images/icons/hint.svg");
}
-#rulesButton {
- background-image: url("../images/icons/info.svg");
+#rulesIcon {
+ background-image: url("../images/icons/question.svg");
}
-#heartButton {
+#heartIcon {
background-image: url("../images/icons/heart.svg");
}
-#customButton {
+#customIcon {
background-image: url("../images/icons/custom.svg");
}
-#calendarButton {
+#shareIcon {
+ background-image: url("../images/icons/share.svg");
+}
+
+#backIcon {
+ background-image: url("../images/icons/back.svg");
+}
+
+#moreIcon {
+ background-image: url("../images/icons/more.svg");
+}
+
+#menuIcon {
+ background-image: url("../images/icons/menu.svg");
+}
+
+#infoIcon {
+ background-image: url("../images/icons/info.svg");
+}
+
+#calendarIcon {
background-image:
url("../images/icons/daily.svg"),
radial-gradient(circle, rgb(239 239 239 / 60%) 30%, rgb(55 54 71));
width: calc(var(--default-font-size) * 2);
}
-#calendarButtonSolved {
+#calendarIconSolved {
background-image: url("../images/icons/daily.svg");
}
-#installButton {
+#installIcon {
background-image: url("../images/icons/install.svg");
}
+
+#playIcon {
+ background-image: url("../images/icons/play.svg");
+}
diff --git a/src/styles/Rules.css b/src/styles/Rules.css
index d7b64bd..7fa416c 100644
--- a/src/styles/Rules.css
+++ b/src/styles/Rules.css
@@ -12,6 +12,15 @@
align-items: center;
}
+.rulesIcon {
+ display: inline-block;
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: contain;
+ width: calc(var(--default-font-size) * 0.75);
+ height: calc(var(--default-font-size) * 0.75);
+}
+
#rulesHeader {
grid-area: header;
}