Skip to content
This repository was archived by the owner on Dec 26, 2022. It is now read-only.
33 changes: 33 additions & 0 deletions components/actionRow/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Grid, GridItem, Center, Text, Circle } from "@chakra-ui/react";
import { getThingName } from '../../lib/utils';
import { getUrl, getStringNoLocale } from '@inrupt/solid-client';
import { IRowComponent } from "../thingList";
import { MUD_LOGIC } from "../../lib/MUD";

/**
* component is responsible for displaying a mudlogic:Action in a row
*/

export default function ActionRow({thing, selectHandler} : IRowComponent): React.ReactElement {
const onRowSelect = (event) => {
selectHandler(thing);
}

return (
<Grid templateColumns="repeat(6, 1fr)" w="80%" margin="auto" marginBottom={10} gap={1}>
<GridItem w="100px" h="100px" colSpan={2} verticalAlign="middle" paddingTop={10} paddingBottom={10}
tag="a" onClick={onRowSelect} style={{ cursor: "pointer" }}>
<Center h="100%"><Circle bg="tomato" w={5} h={5}></Circle></Center>;
</GridItem>

<GridItem colSpan={2} verticalAlign="middle" paddingTop={10} paddingBottom={10}
tag="a" onClick={onRowSelect} style={{ cursor: "pointer" }}>
<Center h="100%"><Text>{getThingName(thing)}</Text></Center>
</GridItem>

<GridItem colSpan={2} verticalAlign="middle" paddingTop={10} paddingBottom={10}
tag="a" onClick={onRowSelect} style={{ cursor: "pointer" }}>
<Center h="100%"><Text>{getStringNoLocale(thing, MUD_LOGIC.actAt)}</Text></Center>
</GridItem>
</Grid>);
}
12 changes: 10 additions & 2 deletions components/character/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { Grid, GridItem, Center, Text, Container } from "@chakra-ui/react";
import { Grid, GridItem, Center, Text, Button, useDisclosure } from "@chakra-ui/react";
import { getThingName } from '../../lib/utils';
import ThingDepiction from "../thingDepiction";
import { getUrl } from '@inrupt/solid-client';
import { IRowComponent } from "../thingList";
import CharacterProfile from '../characterProfile';
import TimerProgressBar from "../timerProgressBar";
import { MUD_CHARACTER } from "../../lib/MUD";
import styles from "./character.module.css";

export default function Character({thing, selectHandler} : IRowComponent): React.ReactElement {
const { isOpen, onOpen, onClose } = useDisclosure();

const onCharacterSelect = (event) => {
selectHandler(thing);
}
Expand All @@ -25,7 +28,7 @@ export default function Character({thing, selectHandler} : IRowComponent): React
}

return (
<Grid templateColumns="repeat(6, 1fr)" w="80%" margin="auto" gap={1} className={styles.characterRow}>
<Grid templateColumns="repeat(7, 1fr)" w="80%" margin="auto" gap={1} className={styles.characterRow}>
<GridItem w="100px" h="100px" colSpan={2} className={styles.profilePic}
tag="a" onClick={onCharacterSelect} style={{ cursor: "pointer" }}>
<ThingDepiction thing={thing} />
Expand All @@ -39,5 +42,10 @@ export default function Character({thing, selectHandler} : IRowComponent): React
<GridItem colSpan={2} className={styles.characterField}>
<Center h="100%">{taskComponent}</Center>
</GridItem>

<GridItem colSpan={1} className={styles.characterField}>
<CharacterProfile character={thing} isOpen={isOpen} onClose={onClose} />
<Center><Button onClick={onOpen}>Profile</Button></Center>
</GridItem>
</Grid>);
}
14 changes: 1 addition & 13 deletions components/gameWindow/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {useState} from "react";
import React from "react";

import {
Tabs,
Expand All @@ -7,29 +7,17 @@ import {
Tab,
TabPanel} from "@chakra-ui/react";

import useTerminalFeed from "../../lib/hooks/useTerminalFeed";
import styles from "./terminal.module.css";

import { WindupChildren } from "windups";
import VisuallyHidden from "@reach/visually-hidden";

import CharacterView from "../characterView";
import WorldView from "../worldView";

export default function GameWindow(): React.ReactElement {

// we duplicate it to display content differently visually and when accessing via screen reader
return (
<Tabs isFitted>
<TabList>
<Tab>Settlements</Tab>
<Tab>Characters</Tab>
</TabList>

<TabPanels>
<TabPanel>
<WorldView />
</TabPanel>
<TabPanel>
<CharacterView />
</TabPanel>
Expand Down
44 changes: 37 additions & 7 deletions components/tables/characterTable/index.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,58 @@
import { useState } from 'react';
import useMudAccount from '../../../lib/hooks/useMudAccount';
import useMudAction from "../../../lib/hooks/useMudAction";
import useMudScene from "../../../lib/hooks/useMudScene";
import { Box, Button, Input, useDisclosure } from "@chakra-ui/react"
import styles from "./characterTable.module.css";
import Character from "../../character";
import CharacterProfile from '../../characterProfile';
import ActionRow from "../../actionRow";

import { MUD, MUD_CHARACTER } from "../../../lib/MUD";
import {ThingListModal} from "../../modals/thingListModal";
import {ThingList} from "../../thingList";
import { Thing } from '@inrupt/solid-client';
import {
Thing,
getUrl,
SolidDataset
} from "@inrupt/solid-client";

export default function CharactersTable({edit} : {edit: boolean}) : React.ReactElement {

const [ newCharName, setNewCharName] = useState("");
const { characters, addCharacter } = useMudAccount();
const [ selectedCharacter, setSelectedCharacter ] = useState(null);
const { discoverActions } = useMudAction();
const { buildScene } = useMudScene();
const [ scene, setScene ] = useState<SolidDataset>(null);
const [ actions, setActions ] = useState<Thing[]>([]);
const { isOpen, onOpen, onClose } = useDisclosure();

const onCharacterAdd = () => {
addCharacter(newCharName);
}

const selectCharacter = (character: Thing): void => {
if(character == null) return;
if(character == null || getUrl(character, MUD_CHARACTER.hasTask)) return;

// Construct a scene (an array of Things)
buildScene([character], true).then((builtScene) => {

setScene(builtScene);

// Discover actions associated to the scene
discoverActions(builtScene).then((actions) => {

// Open the modal to select the desired action
setActions(actions);
onOpen();
});
});
}

setSelectedCharacter(character);
onOpen();
// a scene has been built and an action discovered and selected, time to put it into action!
const selectAction = (action: Thing) : void => {
//TODO
console.log("selected action!");
console.log(action);
}

let editContent = null
Expand All @@ -44,7 +74,7 @@ export default function CharactersTable({edit} : {edit: boolean}) : React.ReactE

return (
<>
<CharacterProfile character={selectedCharacter} isOpen={isOpen} onClose={onClose} />
<ThingListModal things={actions} isOpen={isOpen} rowComponent={ActionRow} onClose={onClose} selectThing={selectAction}/>
<ThingList things={characters} rowComponent={Character} selectThing={selectCharacter} />
{editContent}
</>
Expand Down
1 change: 1 addition & 0 deletions lib/MUD.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,5 @@ export const MUD_LOGIC = {
Task: MUD_LOGIC_BASE_URL + "#Task",
Transit: MUD_LOGIC_BASE_URL + "#Transit",
actAt: MUD_LOGIC_BASE_URL + "#actAt",
parameterConstraintsShape: MUD_LOGIC_BASE_URL + "#parameterConstraintsShape",
}
41 changes: 35 additions & 6 deletions lib/context/mudActionContext/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ import axios, { AxiosResponse } from 'axios';
import {
Thing,
createSolidDataset,
setThing
setThing,
getThingAll,
SolidDataset
} from '@inrupt/solid-client';

import { triplesToTurtle } from "../../utils";
import { triplesToTurtle, parseTurtleToSolidDataset } from "../../utils";
import { MUD_LOGIC } from "../../MUD";
import useMudFederation from '../../hooks/useMudFederation';

Expand All @@ -21,7 +23,7 @@ import useMudFederation from '../../hooks/useMudFederation';
*/

export interface IMUDActionContext {
postTransitTask?: (subjectThing: Thing, destinationLocatable: Thing) => Promise<any>;
discoverActions?: (scene: SolidDataset) => Promise<Thing[]>;
};

export const MudActionContext = createContext<IMUDActionContext>({});
Expand All @@ -37,8 +39,6 @@ export const MudActionProvider = ({
const dataset = setThing(setThing(createSolidDataset(), subject), locatable);
return triplesToTurtle(Array.from(dataset));
}



const postTask = (data: any, taskUri: String) : Promise<AxiosResponse<any>> => {
let endpoint = getFirstConfiguredEndpoint(MUD_LOGIC.Transit);
Expand All @@ -61,10 +61,39 @@ export const MudActionProvider = ({
});
}

const parseContent: (data: string) => Promise<Thing[]> = (data) => {
return new Promise<Thing[]>((resolve, reject) => {
parseTurtleToSolidDataset(data).then((dataset) => {
return resolve(getThingAll(dataset));
});
});
}

/**
* Action discovery
*/
const discoverActions = (scene: SolidDataset) : Promise<Thing[]> => {
return new Promise<Thing[]>((resolve, reject) => {

triplesToTurtle(Array.from(scene)).then((requestData) => {

axios.post(getFirstConfiguredEndpoint(MUD_LOGIC.actionDiscoveryEndpoint), requestData).then((response) => {
if(response && response.data != null) {

// parseContent will transform the Turtle dataset into a list of things
parseContent(response.data).then((actions) => {
return resolve(actions);
});
}
});
});
});
}

return(
<MudActionContext.Provider
value={{
postTransitTask
discoverActions
}}
>
{children}
Expand Down
45 changes: 19 additions & 26 deletions lib/context/mudContentContext/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,13 @@ import {
asUrl,
ThingPersisted,
getThingAll,
SolidDataset,
createSolidDataset,
setThing,
getThing,
} from '@inrupt/solid-client';

import { MUD, MUD_CONTENT } from "../../MUD";
import { parseTurtleToSolidDataset, getThingName, triplesToTurtle } from "../../utils";
import useMudFederation from "../../hooks/useMudFederation";
import useMudScene from "../../hooks/useMudScene";

/**
* The Content Context leverages the Federation to serve Content describing the users' perspective
Expand Down Expand Up @@ -53,6 +51,7 @@ export const MudContentProvider = ({
}): ReactElement => {

const { getFirstConfiguredEndpoint } = useMudFederation();
const { buildScene } = useMudScene();

let recentUris = [];

Expand Down Expand Up @@ -85,16 +84,6 @@ export const MudContentProvider = ({
});
}

const buildSceneTurtleData = (things: Thing[]): Promise<string> => {
let scene: SolidDataset = createSolidDataset();

for(let thing of things) {
scene = setThing(scene, thing);
}

return triplesToTurtle(Array.from(scene));
}

/**
* builds a list of ITerminalMessage objects by getting the primary content data from parameterised things
*/
Expand Down Expand Up @@ -142,19 +131,23 @@ export const MudContentProvider = ({
return new Promise<ITerminalMessage[]>((resolve, reject) => {

// build scene data
buildSceneTurtleData(things).then((requestData) => {
postScene(requestData).then((response) => {
if(response && response.data != null) {

// parseContent has turned the content graph into an array of messages
parseContent(response.data).then((messages) => {
for(let message of messages) {
newMessages.push(getITerminalMessage(message));
}

return resolve(newMessages);
});
}
buildScene(things, true).then((scene) => {

triplesToTurtle(Array.from(scene)).then((requestData) => {

postScene(requestData).then((response) => {
if(response && response.data != null) {

// parseContent has turned the content graph into an array of messages
parseContent(response.data).then((messages) => {
for(let message of messages) {
newMessages.push(getITerminalMessage(message));
}

return resolve(newMessages);
});
}
});
});
});
});
Expand Down
Loading