Skip to content

Commit

Permalink
➕ Add read-only mode
Browse files Browse the repository at this point in the history
  • Loading branch information
GianfrancoBazzani committed Aug 28, 2024
1 parent d23ac6f commit c6d46c7
Show file tree
Hide file tree
Showing 18 changed files with 100 additions and 59 deletions.
3 changes: 3 additions & 0 deletions client/src/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ export const setNetworkId = id => ({ type: SET_NETWORK_ID, id })
export const SET_PLAYER_ADDRESS = "SET_PLAYER_ADDRESS";
export const setPlayerAddress = address => ({ type: SET_PLAYER_ADDRESS, address })

export const SET_GAME_READ_ONLY = "SET_GAME_READ_ONLY";
export const setGameReadOnly = readOnly => ({ type: SET_GAME_READ_ONLY, readOnly })

export const LOAD_GAME_DATA = "LOAD_GAME_DATA";
export const loadGamedata = () => ({ type: LOAD_GAME_DATA, levels: undefined })

Expand Down
31 changes: 24 additions & 7 deletions client/src/containers/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {
deprecationDate,
} from "../utils/networkDeprecation";
import { Helmet } from "react-helmet";
import { store } from "./../store";
import * as actions from "../../src/actions";

class App extends React.Component {
constructor() {
Expand Down Expand Up @@ -121,10 +123,22 @@ class App extends React.Component {
deployWindow[0].style.display = "none";
}

async function continueInReadOnly(){
store.dispatch(actions.loadGamedata());
store.dispatch(actions.setGameReadOnly(true));
const accountConnectionWindow = document.querySelectorAll(
".account-connection-window-bg"
);
accountConnectionWindow[0].style.display = "none";
console.log(store.getState().gamedata.readOnly)
}

async function requestAccounts() {
await window.ethereum.request({ method: "eth_requestAccounts" });
const deployWindow = document.querySelectorAll(".account-connection-window-bg");
deployWindow[0].style.display = "none";
const accountConnectionWindow = document.querySelectorAll(
".account-connection-window-bg"
);
accountConnectionWindow[0].style.display = "none";
window.location.reload();
}

Expand Down Expand Up @@ -202,11 +216,14 @@ class App extends React.Component {
<br />
<p>{strings.accountNotConnectedMessage}</p>
<br />
<button
className="buttons"
onClick={requestAccounts}>
{strings.connectAccount}
</button>
<div className="choice-buttons">
<button className="buttons" onClick={requestAccounts}>
{strings.connectAccount}
</button>
<button className="buttons" onClick={continueInReadOnly}>
{strings.continueInReadOnly}
</button>
</div>
</div>
</div>
{/*not Deployed window*/}
Expand Down
78 changes: 40 additions & 38 deletions client/src/containers/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import PropTypes from "prop-types";
import { ProgressBar } from "react-loader-spinner";
import { svgFilter } from "../utils/svg";
import LeaderIcon from "../components/leaderboard/LeaderIcon";
import { store } from "../store";
// import parse from "html-react-parser";

class Header extends React.Component {
Expand All @@ -24,7 +25,7 @@ class Header extends React.Component {
multiDDOpen: false,
};

if (this.props.web3) {
if (this.props.web3 && !store.getState().gamedata.readOnly) {
window.ethereum.request({ method: "eth_chainId" }).then((id) => {
this.setState({ chainId: Number(id) });
});
Expand Down Expand Up @@ -325,7 +326,8 @@ class Header extends React.Component {
</Link>
</div>
{window.location.pathname === constants.PATH_ROOT &&
!!this.props.web3 && (
!!this.props.web3 &&
!store.getState().gamedata.readOnly && (
<Link
onClick={() => this.toggleDropdownState()}
to={constants.PATH_LEADERBOARD}
Expand All @@ -344,43 +346,43 @@ class Header extends React.Component {
/>
</div>
</div>

<div
className={`single-dropdown --${
this.props.web3 && "--hidden"
}`}
>
<p onClick={() => this.setActiveTab(2)}>
<i className="fas fa-network-wired"></i>
<span>{strings.Networks}</span>
</p>
<div className={this.getDDClassName(2)}>
{Object.values(constants.NETWORKS_INGAME).map(
(network, index) => {
if (network && network.name !== "local") {
if (Number(network.id) === this.state.chainId)
return false; // filter out current network
return (
<div
key={index}
onClick={(e) => {
e.preventDefault();
this.changeNetwork(network);
}}
className="dropdown-pill"
>
<a id={network.name} key={network.name} href="/">
{network.name}
</a>
</div>
);
{this.props.web3 && !store.getState().gamedata.readOnly && (
<div className={`single-dropdown`}>
<p onClick={() => this.setActiveTab(2)}>
<i className="fas fa-network-wired"></i>
<span>{strings.Networks}</span>
</p>
<div className={this.getDDClassName(2)}>
{Object.values(constants.NETWORKS_INGAME).map(
(network, index) => {
if (network && network.name !== "local") {
if (Number(network.id) === this.state.chainId)
return false; // filter out current network
return (
<div
key={index}
onClick={(e) => {
e.preventDefault();
this.changeNetwork(network);
}}
className="dropdown-pill"
>
<a
id={network.name}
key={network.name}
href="/"
>
{network.name}
</a>
</div>
);
}
return null;
}
return null;
}
)}
)}
</div>
</div>
</div>

)}
<div className="single-dropdown">
<p onClick={() => this.setActiveTab(1)}>
<i className="fas fa-globe-americas"></i>
Expand Down Expand Up @@ -438,7 +440,7 @@ class Header extends React.Component {
wrapperClass="progress-bar-wrapper"
visible={true}
/>
{!this.props.web3 && (
{!this.props.web3 && !store.getState().gamedata.readOnly && (
<div
style={{ backgroundColor: "#eddfd6", border: "none" }}
className="alert alert-warning"
Expand Down
3 changes: 2 additions & 1 deletion client/src/containers/Level.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { getLevelKey } from "../utils/contractutil";
import { deployAndRegisterLevel } from "../utils/deploycontract";
import { svgFilter } from "../utils/svg";
import { Helmet } from 'react-helmet';
import { store } from "../store";

class Level extends React.Component {
constructor(props) {
Expand Down Expand Up @@ -331,7 +332,7 @@ class Level extends React.Component {
)}

{/* DEPLOY OR CREATE */}
{this.props.web3 && <button
{ !store.getState().gamedata.readOnly && this.props.web3 && <button
type="button"
className="button-actions"
onClick={
Expand Down
1 change: 1 addition & 0 deletions client/src/gamedata/ar/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"getNewInstance": "احصل على نسخة جديدة",
"accountNotConnectedTitle": "حساب MetaMask غير متصل",
"accountNotConnectedMessage": "لبدء مغامرتك، قم بتوصيل محفظة MetaMask الخاصة بك! تتفاعل لعبتنا بشكل مباشر مع عقود Ethernaut على السلسلة، مما يعني أن أفعالك في اللعبة مسجلة على blockchain. من خلال ربط حساب MetaMask الخاص بك، يمكنك التفاعل بأمان مع هذه العقود الذكية، مما يسمح لك بحل التحديات والتقدم في اللعبة.",
"continueInReadOnly" : "متابعة في القراءة فقط",
"deployMessageTitle": "لم يتم نشر اللعبة",
"deployMessage": "تدُعم اللُعبة حاليًا هذه الشبكات فقط:",
"deprecatedNetwork": "شبكة عفا عليها الزمن",
Expand Down
1 change: 1 addition & 0 deletions client/src/gamedata/en/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"getNewInstance": "Get new instance",
"accountNotConnectedTitle": "MetaMask account not connected",
"accountNotConnectedMessage": "To begin your adventure, connect your MetaMask wallet! Our game interacts directly with Ethernaut on-chain contracts, which means that your actions in the game are recorded on the blockchain. By linking your MetaMask account, you can securely engage with these smart contracts, allowing you to solve challenges, and progress in the game.",
"continueInReadOnly" : "Continue in read-only",
"connectAccount": "Connect",
"deployMessageTitle": "Game not deployed",
"deprecatedNetwork": "Network deprecated",
Expand Down
1 change: 1 addition & 0 deletions client/src/gamedata/es/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"getNewInstance": "Nueva instancia",
"accountNotConnectedTitle": "Cuenta MetaMask no conectada",
"accountNotConnectedMessage": "Para comenzar tu aventura, conecta tu billetera MetaMask. Nuestro juego interactúa directamente con los contratos en cadena de Ethernaut, lo que significa que tus acciones en el juego quedan registradas en la cadena de bloques. Al vincular tu cuenta MetaMask, puedes interactuar de forma segura con estos contratos inteligentes, lo que te permite resolver desafíos y progresar en el juego.",
"continueInReadOnly" : "Modo solo lectura",
"deployMessageTitle": "Juego no desplegado",
"deprecatedNetwork": "Red obsoleta",
"networkBeingDeprecated": "Red en desuso",
Expand Down
1 change: 1 addition & 0 deletions client/src/gamedata/fr/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"getNewInstance": "Créer une nouvelle instance",
"accountNotConnectedTitle": "Compte MetaMask non connecté",
"accountNotConnectedMessage": "Pour commencer votre aventure, connectez votre portefeuille MetaMask ! Notre jeu interagit directement avec les contrats on-chain d'Ethernaut, ce qui signifie que vos actions dans le jeu sont enregistrées sur la blockchain. En liant votre compte MetaMask, vous pouvez interagir en toute sécurité avec ces contrats intelligents, vous permettant de résoudre des défis et de progresser dans le jeu.",
"continueInReadOnly" : "mode lecture seule",
"deployMessageTitle": "Jeu non déployé",
"deprecatedNetwork": "Réseau obsolète",
"networkBeingDeprecated": "Réseau désaffecté",
Expand Down
1 change: 1 addition & 0 deletions client/src/gamedata/ja/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"getNewInstance": "インスタンスの生成",
"accountNotConnectedTitle": "MetaMask アカウントが接続されていません",
"accountNotConnectedMessage": "冒険を始めるには、MetaMask ウォレットを接続してください。私たちのゲームは Ethernaut オンチェーン コントラクトと直接やり取りします。つまり、ゲーム内でのアクションはブロックチェーンに記録されます。MetaMask アカウントをリンクすることで、これらのスマート コントラクトに安全に関与し、課題を解決してゲームを進めることができます。",
"continueInReadOnly" : "読み取り専用モード",
"deployMessageTitle": "ゲームが展開されていません",
"deployMessage": "現在、ゲームはこれらのネットワークのみをサポートしています:",
"deprecatedNetwork": "ネットワークは放棄されています",
Expand Down
1 change: 1 addition & 0 deletions client/src/gamedata/pt_br/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"getNewInstance": "Obter nova instância",
"accountNotConnectedTitle": "Conta MetaMask não ligada",
"accountNotConnectedMessage": "Para começar a sua aventura, ligue a sua carteira MetaMask! O nosso jogo interage diretamente com os contratos on-chain do Ethernaut, o que significa que as suas ações no jogo são registadas na blockchain. Ao ligar a sua conta MetaMask, pode interagir com segurança com estes contratos inteligentes, permitindo-lhe resolver desafios e progredir no jogo.",
"continueInReadOnly" : "modo de leitura apenas",
"deployMessageTitle": "Jogo não implantado",
"deprecatedNetwork": "Rede obsoleta",
"networkBeingDeprecated": "Rede sendo obsoleta",
Expand Down
1 change: 1 addition & 0 deletions client/src/gamedata/ru/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"getNewInstance": "Создать новый инстанс",
"accountNotConnectedTitle": "Учетная запись MetaMask не подключена",
"accountNotConnectedMessage": "Чтобы начать приключение, подключите свой кошелек MetaMask! Наша игра напрямую взаимодействует с ончейн-контрактами Ethernaut, что означает, что ваши действия в игре записываются в блокчейн. Подключив свой аккаунт MetaMask, вы можете безопасно взаимодействовать с этими смарт-контрактами, что позволит вам решать задачи и продвигаться в игре.",
"continueInReadOnly" : "режим только для чтения",
"deployMessageTitle": "Игра не развернута",
"deprecatedNetwork": "заброшенная сеть",
"networkBeingDeprecated": "сеть в процессе закрытия",
Expand Down
1 change: 1 addition & 0 deletions client/src/gamedata/tr/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"getNewInstance": "Yeni durum al",
"accountNotConnectedTitle": "MetaMask hesabı bağlı değil",
"accountNotConnectedMessage": "Maceranıza başlamak için MetaMask cüzdanınızı bağlayın! Oyunumuz doğrudan Ethernaut zincir üstü sözleşmeleriyle etkileşime girer, bu da oyundaki eylemlerinizin blok zincirinde kaydedildiği anlamına gelir. MetaMask hesabınızı bağlayarak bu akıllı sözleşmelerle güvenli bir şekilde etkileşime girebilir, zorlukları çözebilir ve oyunda ilerleyebilirsiniz.",
"continueInReadOnly" : "salt okunur modu",
"deployMessageTitle": "Oyun dağıtılmadı",
"deprecatedNetwork": "Ağ kullanımdan kaldırıldı",
"networkBeingDeprecated": "Ağ kullanımdan kaldırılıyor",
Expand Down
1 change: 1 addition & 0 deletions client/src/gamedata/zh_cn/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"getNewInstance": "生成新实例",
"accountNotConnectedTitle": "MetaMask 帐户未连接",
"accountNotConnectedMessage": "要开始您的冒险,请连接您的 MetaMask 钱包!我们的游戏直接与 Ethernaut 链上合约交互,这意味着您在游戏中的行为会记录在区块链上。通过链接您的 MetaMask 帐户,您可以安全地与这些智能合约互动,从而让您解决​​挑战并在游戏中取得进展。",
"continueInReadOnly" : "只读模式",
"deployMessageTitle": "Game not deployed",
"deprecatedNetwork": "Network deprecated",
"networkBeingDeprecated": "Network being deprecated",
Expand Down
2 changes: 1 addition & 1 deletion client/src/gamedata/zh_tw/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"getNewInstance": "產生新實例",
"accountNotConnectedTitle": "MetaMask 帳戶未連接",
"accountNotConnectedMessage": "要開始您的冒險,請連接您的 MetaMask 錢包!我們的遊戲直接與 Ethernaut 鏈上合約交互,這意味著您在遊戲中的行為都會記錄在區塊鏈上。透過連結您的 MetaMask 帳戶,您可以安全地使用這些智能合約,從而解決挑戰並在遊戲中取得進展。",
"continueInReadOnly" : "唯讀模式",
"deployMessageTitle": "遊戲未部署",
"deprecatedNetwork": "網路已棄用",
"networkBeingDeprecated": "網路將來將被棄用",
Expand All @@ -37,7 +38,6 @@
"deployGame": "部署遊戲",
"switchToSepolia": "切換到Sepolia",
"continueAnyway": "仍然繼續",

"deployLevel": "部署級別",
"helperDeployAllContracts": "在當前網絡上部署所有其餘合同。",
"confirmMainnetDeploy": "您在主網上,遊戲沒有貨幣價值,您不應在此網絡中部署。",
Expand Down
11 changes: 6 additions & 5 deletions client/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ if (!window.ethereum) {
} else {
window.ethereum.request({ method: "eth_accounts" }).then((res) => {
if (res.length !== 0) {
console.log(res)
window.ethereum.request({ method: "eth_chainId" }).then((res) => {
store.dispatch(actions.setNetworkId(parseInt(res)));
store.dispatch(actions.loadGamedata());
Expand Down Expand Up @@ -79,10 +78,12 @@ root.render(
// Post-load actions.
window.addEventListener("load", async () => {
// Check if any MetaMask account is connected to the frontend
const eth_accounts = await window.ethereum.request({ method: "eth_accounts" });
const accountConnected = eth_accounts.length !== 0;

if (window.ethereum && accountConnected) {
let accountConnected = false;
if(window.ethereum) {
const eth_accounts = await window.ethereum.request({ method: "eth_accounts" });
accountConnected = eth_accounts.length !== 0;
}
if (accountConnected) {
window.web3 = new constants.Web3(window.ethereum);
try {
await window.ethereum.request({ method: `eth_requestAccounts` });
Expand Down
8 changes: 8 additions & 0 deletions client/src/middlewares/setGameReadOnly.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import * as actions from '../actions';

const setGameReadOnly = store => next => action => {
if (action.type !== actions.SET_GAME_READ_ONLY) return next(action)

}

export default setGameReadOnly
7 changes: 7 additions & 0 deletions client/src/reducers/gamedataReducer.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as actions from '../actions';

const initialState = {
readOnly: false,
ethernautAddress: undefined,
activeLevel: undefined,
levels: []
Expand All @@ -9,6 +10,12 @@ const initialState = {
const gameDataReducer = function(state = initialState, action) {
switch(action.type) {

case actions.SET_GAME_READ_ONLY:
return {
...state,
readOnly: action.readOnly
}

case actions.LOAD_GAME_DATA:
return {
...state,
Expand Down
7 changes: 0 additions & 7 deletions client/src/styles/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -310,13 +310,6 @@ nav li {
text-align: center;
}

.account-connection-window button {
display: block;
margin-left: auto;
margin-right: auto;
width: fit-content;
}

.account-connection-window p {
font-size: 1.1em;
text-align: justify;
Expand Down

0 comments on commit c6d46c7

Please sign in to comment.