Skip to content
This repository was archived by the owner on May 25, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { NavBar, Notification } from '@components';
import { useTranslation } from 'react-i18next';
import { NavBarContainer } from './children';
import { LanguageDropdown } from '@util-components';
import { buildPathFromWebId, ldflexHelper, errorToaster } from '@utils';
import { ldflexHelper, errorToaster, storageHelper } from '@utils';

type Props = {
webId: string
Expand Down Expand Up @@ -53,9 +53,8 @@ const AuthNavBar = React.memo((props: Props) => {
/**
* Get user's game inbox path from pod.
*/
const appInbox = await ldflexHelper.discoverInbox(
buildPathFromWebId(webId, `${process.env.REACT_APP_TICTAC_PATH}settings.ttl`)
);
const appStorage = await storageHelper.getAppStorage(webId);
const appInbox = await ldflexHelper.discoverInbox(`${appStorage}settings.ttl`);

/**
* create an inbox object to send over notification component
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
ldflexHelper,
errorToaster,
successToaster,
buildPathFromWebId,
storageHelper,
notification as helperNotification
} from '@utils';
import { GameFormWrapper, BtnDiv } from './game-form.styles';
Expand Down Expand Up @@ -54,10 +54,8 @@ const GameForm = ({ webId, sendNotification, opponent, setOpponent }: Props) =>
/**
* Get full opponent game path
*/
const gameSettings = buildPathFromWebId(
opponent,
`${process.env.REACT_APP_TICTAC_PATH}/settings.ttl`
);
const appPath = await storageHelper.getAppStorage(opponent);
const gameSettings = `${appPath}settings.ttl`;
/**
* Find opponent inboxes from a document link
*/
Expand Down Expand Up @@ -136,10 +134,8 @@ const GameForm = ({ webId, sendNotification, opponent, setOpponent }: Props) =>
const onSubmit = async e => {
try {
e.preventDefault();
const documentPath = buildPathFromWebId(
webId,
`${process.env.REACT_APP_TICTAC_PATH}${documentUri}`
);
const appPath = await storageHelper.getAppStorage(webId);
const documentPath = `${appPath}${documentUri}`;

if (!opponent || opponent === '') {
errorToaster(t('game.opponentMissing'), t('game.errorTitle'));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ import tictactoeShape from '@contexts/tictactoe-shape.json';
import {
ldflexHelper,
errorToaster,
buildPathFromWebId,
storageHelper,
notification as helperNotification
} from '@utils';
import { GameStatusList, GameStatus, KnownInboxes } from '@constants';
import { Wrapper, ListWrapper, GameListContainers, GameListHeader } from './list.style';
import GameItem from './children';

let oldTimestamp;
let appPath;

type Props = { webId: String, gamePath: String, sendNotification: Function };
type GameListProps = { title: String, games: Array, webId: String, deleteGame: Function };

Expand Down Expand Up @@ -113,12 +115,12 @@ const List = ({ webId, gamePath, sendNotification }: Props) => {
// Change status to resigned
await ldflex[url][statusPredicate].replace(status, GameStatus.RESIGNED);

// Send notification
const gameSettings = buildPathFromWebId(
actor.webId,
`${process.env.REACT_APP_TICTAC_PATH}settings.ttl`
);
if (!appPath) {
appPath = await storageHelper.getAppStorage(actor.webId);
}

// Send notification
const gameSettings = `${appPath}settings.ttl`;
const { GLOBAL, GAME } = KnownInboxes;

const inboxes = await helperNotification.findUserInboxes([
Expand Down Expand Up @@ -228,8 +230,9 @@ const List = ({ webId, gamePath, sendNotification }: Props) => {
*/
const init = useCallback(async () => {
setIsLoading(true);
const url = buildPathFromWebId(webId, process.env.REACT_APP_TICTAC_PATH);
const inviteGamesUrl = `${url}data.ttl`;
appPath = await storageHelper.getAppStorage(webId);
const inviteGamesUrl = `${appPath}data.ttl`;

/**
* Check if user pod has data.ttl file where will live
* opponent games if not show error message
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { Fragment, useState, useEffect, useCallback } from 'react';
import { LiveUpdate, useNotification } from '@inrupt/solid-react-components';
import { useTranslation } from 'react-i18next';
import { ldflexHelper, buildPathFromWebId, errorToaster } from '@utils';
import { ldflexHelper, storageHelper, errorToaster } from '@utils';
import { Form, List } from './children';
import { Section, Wrapper } from '../tic-tac-toe.style';

Expand All @@ -24,8 +24,8 @@ const GameListPage = ({ webId }) => {

const init = async () => {
try {
const url = buildPathFromWebId(webId, process.env.REACT_APP_TICTAC_PATH);
const gamePath = await ldflexHelper.createContainer(url);
const gameUrl = await storageHelper.getAppStorage(webId);
const gamePath = await ldflexHelper.createContainer(gameUrl);
if (gamePath) {
await createInbox(`${gamePath}inbox/`, gamePath);
setGamePath(gamePath);
Expand Down Expand Up @@ -64,7 +64,7 @@ const GameListPage = ({ webId }) => {
}}
/>
{gamePath && (
<LiveUpdate subscribe={buildPathFromWebId(webId, process.env.REACT_APP_TICTAC_PATH)}>
<LiveUpdate subscribe={gamePath}>
<List {...{ webId, gamePath, sendNotification }} />
</LiveUpdate>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { Fragment, useEffect, useState, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { useLiveUpdate, useNotification } from '@inrupt/solid-react-components';
import moment from 'moment';
import { ldflexHelper, errorToaster, buildPathFromWebId, notification } from '@utils';
import { ldflexHelper, storageHelper, errorToaster, notification } from '@utils';
import ldflex from '@solid/query-ldflex';
import { namedNode } from '@rdfjs/data-model';
import tictactoeShape from '@contexts/tictactoe-shape.json';
Expand Down Expand Up @@ -30,21 +30,20 @@ const Game = ({ webId, gameURL, history }: Props) => {
const [gameData, setGameData] = useState({});
const [result, setResult] = useState(null);
const [isProcessing, setIsProcessing] = useState(false);
const inboxUrl = buildPathFromWebId(webId, process.env.REACT_APP_TICTAC_INBOX);
const { createNotification, createInbox } = useNotification(webId);
const [rival, setRival] = useState(null);
const { t } = useTranslation();

let appPath = '';

const sendNotification = useCallback(
async (player, content) => {
try {
/**
* Get full opponent game path
*/
const gameSettings = buildPathFromWebId(
player,
`${process.env.REACT_APP_TICTAC_PATH}settings.ttl`
);
appPath = await storageHelper.getAppStorage(webId);
const gameSettings = `${appPath}settings.ttl`;

/**
* Find opponent inboxes from a document link
Expand Down Expand Up @@ -77,7 +76,7 @@ const Game = ({ webId, gameURL, history }: Props) => {
errorToaster(error.message, 'Error');
}
},
[gameData, inboxUrl]
[gameData, appPath]
);

/**
Expand Down Expand Up @@ -162,7 +161,7 @@ const Game = ({ webId, gameURL, history }: Props) => {
* Adds the game document as a link in the opponent's data.ttl file
*/
const addGameToList = async () => {
const url = buildPathFromWebId(webId, process.env.REACT_APP_TICTAC_PATH);
const url = await storageHelper.getAppStorage(webId);
await ldflex[`${url}/data.ttl`]['ldp:contains'].add(namedNode(gameURL));
};

Expand Down Expand Up @@ -391,16 +390,23 @@ const Game = ({ webId, gameURL, history }: Props) => {
[gameData]
);

/**
* Initialize the app storage location
*/
const initAppStorage = useCallback(async () => {
const gamePath = await storageHelper.getAppStorage(webId);
if (gameURL) {
createInbox(`${gamePath}inbox/`, gamePath);
getInitialGame();
}
}, [webId]);

/**
* Executes when the game is mounted the first time
*/
useEffect(() => {
try {
const gamePath = buildPathFromWebId(webId, process.env.REACT_APP_TICTAC_PATH);
if (gameURL) {
createInbox(`${gamePath}inbox/`, gamePath);
getInitialGame();
}
initAppStorage();
} catch (e) {
/**
* Check if something fails when we try to create a inbox
Expand Down
9 changes: 2 additions & 7 deletions generators/app/templates/src/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,14 @@ import { expandedProperty } from './context';
import { successToaster, errorToaster } from './toaster';
import * as ldflexHelper from './ldflex-helper';
import * as notification from './notification';
import * as storageHelper from './storage';

function* entries(obj) {
for (const key of Object.keys(obj)) {
yield [key, obj[key]];
}
}

function buildPathFromWebId(webid, path) {
if (!webid) return false;
const domain = new URL(typeof webid === 'object' ? webid.webId : webid).origin;
return `${domain}/${path}`;
}

function checkAppPermissions(userAppPermissions, appPermissions) {
const userAppPermission = userAppPermissions.sort().toString();
const appPermission = appPermissions.sort().toString();
Expand All @@ -27,9 +22,9 @@ export {
expandedProperty,
entries,
ldflexHelper,
storageHelper,
successToaster,
errorToaster,
buildPathFromWebId,
checkAppPermissions,
notification
};
38 changes: 38 additions & 0 deletions generators/app/templates/src/utils/storage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import data from '@solid/query-ldflex';

const appPath = process.env.REACT_APP_TICTAC_PATH;

/**
* Creates a valid string that represents the application path. This is the
* default value if no storage predicate is discovered
* @param webId
* @param path
* @returns {*}
*/
export const buildPathFromWebId = (webId, path) => {
if (!webId) return false;
const domain = new URL(typeof webId === 'object' ? webId.webId : webId).origin;
return `${domain}/${path}`;
};

/**
* Helper function to check for the user's pod storage value. If it doesn't exist, we assume root of the pod
* @returns {Promise<string>}
*/
export const getAppStorage = async webId => {
const podStoragePath = await data[webId].storage;
let podStoragePathValue =
podStoragePath && podStoragePath.value.trim().length > 0 ? podStoragePath.value : '';

// Make sure that the path ends in a / so it is recognized as a folder path
if (podStoragePathValue && !podStoragePathValue.endsWith('/')) {
podStoragePathValue = `${podStoragePathValue}/`;
}

// If there is no storage value from the pod, use webId as the backup, and append the application path from env
if (!podStoragePathValue || podStoragePathValue.trim().length === 0) {
return buildPathFromWebId(webId, appPath);
}

return `${podStoragePathValue}${appPath}`;
};