diff --git a/app/authentication/authentication-client.tsx b/app/authentication/authentication-client.tsx deleted file mode 100644 index 323ec7f..0000000 --- a/app/authentication/authentication-client.tsx +++ /dev/null @@ -1,73 +0,0 @@ - -'use client' - -import { MouseEventHandler, MouseEvent, useState } from 'react' - -import * as Ably from 'ably' -import Logger, { LogEntry } from '../../components/logger' -import SampleHeader from '../../components/SampleHeader' -import { AblyProvider, useAbly, useConnectionStateListener } from 'ably/react' - -export default function Authentication() { - - const client = new Ably.Realtime.Promise ({ authUrl: '/token', authMethod: 'POST' }); - - return ( - -
-
- -
- Authenticate and establish a persistant bi-directional connection to the Ably platform. -
- -
-
-
- ) -} - -const ConnectionStatus = () => { - - const ably = useAbly(); - - const [logs, setLogs] = useState>([]) - const [connectionState, setConnectionState] = useState('unknown') - - useConnectionStateListener((stateChange) => { - setConnectionState(stateChange.current) - setLogs(prev => [...prev, new LogEntry(`Connection state change: ${stateChange.previous} -> ${stateChange.current}`)]) - }) - - const connectionToggle: MouseEventHandler = (_event: MouseEvent) => { - if(connectionState === 'connected') { - ably.connection.close() - } - else if(connectionState === 'closed') { - ably.connection.connect() - } - } - - return ( - <> -
-
-
- connection status -   - =  - - {connectionState} - -
-
-
-
- -
-
-
- - - ) -} \ No newline at end of file diff --git a/app/authentication/page.tsx b/app/authentication/page.tsx deleted file mode 100644 index 622bc79..0000000 --- a/app/authentication/page.tsx +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Warning: Opening too many live preview tabs will slow down performance. - * We recommend closing them after you're done. - */ -import React from "react"; -import "../global.css"; -import dynamic from 'next/dynamic'; -import Sidebar from "../../components/Sidebar.tsx"; - -const AuthenticationClient = dynamic(() => import('./authentication-client.tsx'), { - ssr: false, -}) - -const Authentication = () => { - - const pageId = "Authentication"; - - return ( - <> - -
- -
- - ) -}; - -export default Authentication; \ No newline at end of file diff --git a/app/game-rules/page.tsx b/app/game-rules/page.tsx index bd5281f..4256906 100644 --- a/app/game-rules/page.tsx +++ b/app/game-rules/page.tsx @@ -4,7 +4,6 @@ */ import React from "react"; import "../global.css"; -import Sidebar from "../../components/Sidebar"; const Home = () => { @@ -15,29 +14,28 @@ const Home = () => {
-
-
-
- - Game rules  - -

On the board are predators and prey.

- -

The prey gain energy by feeding off the empty white spaces

- -

If two prey bump into each other, they procreate, incurring an energy cost, and spawning another prey in that space.

- -

The predators gain energy by feeding on the prey, and they can also procreate by bumping into each other.

-

- -

-

You have a character that you can move around. By bumping into the prey you can absorb the them and gain their energy, but if you instead absorb the predators you lose energy equal to their energy.

+
+
+
{/* Increased line height */} + + Game rules  + +

On the board are predators and prey.

+ +

The prey gain energy by feeding off the empty white spaces

+ +

If two prey bump into each other, they procreate, incurring an energy cost, and spawning another prey in that space.

+ +

The predators gain energy by feeding on the prey, and they can also procreate by bumping into each other.

+

+

You have a character that you can move around. By bumping into the prey you can absorb them and gain their energy, but if you instead absorb the predators you lose energy equal to their energy.

-

If you bump into another player, the player with the higher energy absorbs the lower energy. If you gain energy, you grow bigger, and move less quickly.

+

If you bump into another player, the player with the higher energy absorbs the lower energy. If you gain energy, you grow bigger, and move less quickly.

+
-
-
+ + ) } diff --git a/app/history/history-client.tsx b/app/history/history-client.tsx deleted file mode 100644 index e6a3558..0000000 --- a/app/history/history-client.tsx +++ /dev/null @@ -1,139 +0,0 @@ -'use client' - -import * as Ably from 'ably'; - -import { AblyProvider, useChannel } from "ably/react" -import { useState, useEffect } from 'react' -import Logger, { LogEntry } from '../../components/logger'; -import SampleHeader from '../../components/SampleHeader'; - -export default function Presence() { - - const client = new Ably.Realtime.Promise ({ authUrl:'/token', authMethod: 'POST' }); - - return ( - -
-
-
- -
- Retrieve a history of messages that have been published to a channel. - Messages are only stored for 2 minutes by default. In order for them - to be stored for longer you should enable the  - - Persist all messages -   - channel rule -  for - the  - - status-updates - -  channel in your Ably app   -
-
-
-
- Alert -
-
- Important: You need to - publish at least 1 message from the  - - Pub/Sub Channels example - -  to see history log. -
- -
- -
-
-
- ) -} - -function HistoryMessages() { - - const [realtimeLogs, setRealtimeLogs] = useState>([]) - const [historicalLogs, setHistoricalLogs] = useState>([]) - - const { channel } = useChannel("status-updates", (message: Ably.Types.Message) => { - console.log(message); - setRealtimeLogs(prev => [...prev, new LogEntry(`✉️ event name: ${message.name} text: ${message.data.text}`)]) - }); - - useEffect(() => { - const getHistory = async () => { - let history: Ably.Types.PaginatedResult = await channel.history() - do { - history.items.forEach(message => { - setHistoricalLogs(prev => [ - ...prev, - new LogEntry(`"${message.data.text}" sent at ${new Date(message.timestamp).toISOString()}`) - ]) - }) - history = await history.next() - } - while(history) - } - getHistory() - }, []) - - return ( - <> -
-
- history -
- { - historicalLogs.length > 0? ( - - ) : ( -
-
-

No historical messages found

-
-
- )} - -
-
-
- realtime -
- { - realtimeLogs.length > 0? ( - - ) : ( -
-
-

No realtime messages received yet

-
-
- )} -
- - //
- //
- //

History

- // { - // historicalLogs.length > 0? - // - // : - //

No historical messages found

- // } - //
- //
- //

Realtime

- // { - // realtimeLogs.length > 0? - // - // : - //

No realtime messages received yet

- // } - //
- //
- ) -} diff --git a/app/history/page.tsx b/app/history/page.tsx deleted file mode 100644 index b7692e4..0000000 --- a/app/history/page.tsx +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Warning: Opening too many live preview tabs will slow down performance. - * We recommend closing them after you're done. - */ -import React from "react"; -import "../global.css"; -import dynamic from 'next/dynamic'; -import MenuFooter from "../../components/FooterItem.tsx"; -import MenuItem from "../../components/MenuItem.tsx"; -import Sidebar from "../../components/Sidebar.tsx"; - -const HistoryClient = dynamic(() => import('./history-client.tsx'), { - ssr: false, -}) - -const History = () => { - - const pageId = "History" - - return ( - <> - -
- -
- - ) -} - -export default History; diff --git a/app/page.tsx b/app/page.tsx index 2ebe059..6dc2bdc 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -4,7 +4,6 @@ */ import React from "react"; import "./global.css"; -import Sidebar from "../components/Sidebar"; const Home = () => { @@ -12,11 +11,36 @@ const Home = () => { return ( <> - +
+
+
+
+
+
{/* Increased line height */} + + Game rules  + +

On the board are predators and prey.

+ +

The prey gain energy by feeding off the empty white spaces

+ +

If two prey bump into each other, they procreate, incurring an energy cost, and spawning another prey in that space.

+ +

The predators gain energy by feeding on the prey, and they can also procreate by bumping into each other.

+

+

You have a character that you can move around. By bumping into the prey you can absorb them and gain their energy, but if you instead absorb the predators you lose energy equal to their energy.

+ +

If you bump into another player, the player with the higher energy absorbs the lower energy. If you gain energy, you grow bigger, and move less quickly.

+
+
+
+
+
+
Spatial Ecology Game
@@ -34,7 +58,7 @@ const Home = () => {
- Game Rules + Example
@@ -46,7 +70,7 @@ const Home = () => {
- Explore now + See video here
diff --git a/app/presence/page.tsx b/app/presence/page.tsx deleted file mode 100644 index 0309a72..0000000 --- a/app/presence/page.tsx +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Warning: Opening too many live preview tabs will slow down performance. - * We recommend closing them after you're done. - */ -import React from "react"; -import "../global.css"; -import dynamic from 'next/dynamic'; -import Sidebar from "../../components/Sidebar.tsx"; - -const PresenceClient = dynamic(() => import('./presence-client.tsx'), { - ssr: false, -}) - -const Presence = () => { - - const pageId = "Presence" - - return ( - <> - -
- -
- - ) -} - -export default Presence; diff --git a/app/presence/presence-client.tsx b/app/presence/presence-client.tsx deleted file mode 100644 index 9952506..0000000 --- a/app/presence/presence-client.tsx +++ /dev/null @@ -1,82 +0,0 @@ -'use client' - -import * as Ably from 'ably'; -import names from 'random-names-generator' - -import { AblyProvider, useAbly, usePresence } from "ably/react" -import { useState, ReactElement, FC } from 'react' -import Logger, { LogEntry } from '../../components/logger'; -import SampleHeader from '../../components/SampleHeader'; - -export default function Presence() { - - const [randomName] = useState(names.random()); - const [isOnline, setIsOnline] = useState(false) - - const client = new Ably.Realtime.Promise ({ authUrl:'/token', authMethod: 'POST', clientId: randomName }); - - function toggleState(val: boolean) { - setIsOnline(val) - } - - return ( - -
- - ) -} - -const PresenceMessages: FC = ({toggle}): ReactElement => { - - const [logs, setLogs] = useState>([]) - const client = useAbly(); - - const { presenceData, updateStatus } = usePresence("room", {'status':'available'}, (member) => { - setLogs(prev => [...prev, new LogEntry(`action: ${member.action} clientId: ${member.clientId}`)]) - }); - - return ( - <> -
-
-
-
    - {presenceData.map((member) => { - return (
  • {member.clientId}
  • ) - })} -
-
-
-
-
- -
-
-
- - - ) -} diff --git a/app/pub-sub/page.tsx b/app/pub-sub/page.tsx deleted file mode 100644 index c90a892..0000000 --- a/app/pub-sub/page.tsx +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Warning: Opening too many live preview tabs will slow down performance. - * We recommend closing them after you're done. - */ -import React from "react"; -import "../global.css"; -import dynamic from 'next/dynamic'; -import Sidebar from "../../components/Sidebar.tsx"; - -const PubSubClient = dynamic(() => import('./pubsub-client.tsx'), { - ssr: false, -}) - -const PubSub = () => { - - const pageId="PubSubChannels" - - return ( - <> - -
- -
- - ) -} - -export default PubSub; diff --git a/app/pub-sub/pubsub-client.tsx b/app/pub-sub/pubsub-client.tsx deleted file mode 100644 index 5972f78..0000000 --- a/app/pub-sub/pubsub-client.tsx +++ /dev/null @@ -1,73 +0,0 @@ -'use client' - -import * as Ably from 'ably'; -import { AblyProvider, useAbly, useChannel } from "ably/react" -import { MouseEventHandler, MouseEvent, useState } from 'react' -import Logger, { LogEntry } from '../../components/logger'; -import SampleHeader from '../../components/SampleHeader'; - -export default function PubSubClient() { - - const client = new Ably.Realtime.Promise ({ authUrl: '/token', authMethod: 'POST' }); - - return ( - -
-
- -
- Publish messages on channels and subscribe to channels to receive messages. Click Publish from Client to publish a message on a channel from the web browser client. Click Publish from Server to publish a message from a serverless function. -
- -
-
-
- ) -} - -function PubSubMessages() { - - const [logs, setLogs] = useState>([]) - - const { channel } = useChannel("status-updates", (message: Ably.Types.Message) => { - setLogs(prev => [...prev, new LogEntry(`✉️ event name: ${message.name} text: ${message.data.text}`)]) - }); - - const [messageText, setMessageText] = useState('A message') - - const publicFromClientHandler: MouseEventHandler = (_event: MouseEvent) => { - if(channel === null) return - channel.publish('update-from-client', {text: `${messageText} @ ${new Date().toISOString()}`}) - } - - const publicFromServerHandler: MouseEventHandler = (_event: MouseEvent) => { - fetch('/publish', { - 'method': 'POST', - 'headers': { - 'content-type': 'application/json', - }, - 'body': JSON.stringify({text: `${messageText} @ ${new Date().toISOString()}`}) - }) - } - - return ( - <> -
- setMessageText(e.target.value)} /> -
-
-
- -
-
-
-
- -
-
-
-
- - - ) -} \ No newline at end of file diff --git a/app/publish/route.ts b/app/publish/route.ts deleted file mode 100644 index 16970d9..0000000 --- a/app/publish/route.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { NextRequest, NextResponse } from 'next/server' -import * as Ably from "ably/promises" - -export async function POST(req: Request) { - if (!process.env.ABLY_API_KEY) { - return NextResponse.json({ errorMessage: `Missing ABLY_API_KEY environment variable. - If you're running locally, please ensure you have a ./.env file with a value for ABLY_API_KEY=your-key. - If you're running in Netlify, make sure you've configured env variable ABLY_API_KEY. - Please see README.md for more details on configuring your Ably API Key.`, - },{ - status: 500, - headers: new Headers({ - "content-type": "application/json" - }) - }); - } - - const client = new Ably.Rest(process.env.ABLY_API_KEY) - - var channel = client.channels.get('status-updates') - const message: { text: string } = await req.json() - - // By publishing via the serverless function you can perform - // checks in a trusted environment on the data being published - const disallowedWords = [ 'foo', 'bar', 'fizz', 'buzz' ] - - const containsDisallowedWord = disallowedWords.some(word => { - return message.text.match(new RegExp(`\\b${word}\\b`)) - }) - - if(containsDisallowedWord) { - return new Response("", { 'status': 403 }); - } - - await channel.publish('update-from-server', message) - return new Response(""); -} diff --git a/components/MenuItem.tsx b/components/MenuItem.tsx deleted file mode 100644 index 43a69a6..0000000 --- a/components/MenuItem.tsx +++ /dev/null @@ -1,18 +0,0 @@ -interface MenuItemProps { - menuItemText:string, - menuItemActive:boolean, - menuItemLink:string - } - - export default function MenuItem(props:MenuItemProps) { - return ( - - ) - } - \ No newline at end of file diff --git a/components/Sidebar.tsx b/components/Sidebar.tsx deleted file mode 100644 index fa687de..0000000 --- a/components/Sidebar.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import MenuItem from "./MenuItem"; -import {Types} from "ably"; -import { useChannel, usePresence } from 'ably/react'; - - -export default function Sidebar(props: {pageId : string}) { - - const menuItems = [ - { - menuItemId: "Current player", - menuItemText: "You - click to name yourself", - menuItemActive: true, - }, - { - menuItemId: "Player 2", - menuItemText: "Player 2", - menuItemActive: false, - }, - - ] - - - return( -
-
- AblyLogoWithText -
- {menuItems.map( - ({ - menuItemId, - menuItemText - }) => ( - - ) - )} -
-
-
- Rule -
-
- Rule -
- - -
-
-
- ) -} \ No newline at end of file diff --git a/components/logger.tsx b/components/logger.tsx deleted file mode 100644 index be38fbb..0000000 --- a/components/logger.tsx +++ /dev/null @@ -1,52 +0,0 @@ -export class LogEntry { - public timestamp: Date - public message: string - - constructor(message: string) { - this.timestamp = new Date() - this.message = message - } -} - -export type LoggingProps = { - logEntries: Array, - displayHeader: boolean -} - -export default function Logger({ logEntries, displayHeader }: LoggingProps) { - return ( -
- { displayHeader && -
- Message log -
- } -
-
-
- Red - Yellow - Green -
-
- -
-
-
    - { - // Show the newest log entry at the top - logEntries.map((logEntry: LogEntry, index: number) => { - return ( -
  • - {index+1}  {logEntry.message} -
  • - )} - ) - } -
-
-
-
-
- ) -} \ No newline at end of file