From 62ec00596ea2ca142124f1d2e8f89abb234e4bdc Mon Sep 17 00:00:00 2001 From: jesQM Date: Thu, 23 Apr 2020 18:36:51 +0200 Subject: [PATCH 1/6] Added possibility to see shared routes --- src/components/navBar/navBar.js | 4 ++ src/components/podService/podStoreHandler.js | 5 +- src/components/routeList/RouteCard.js | 19 ++++++- src/i18n.js | 2 + src/model/RouteManager.js | 11 +++- src/pages/Home.js | 2 + src/pages/RouteList.js | 21 +++++++- src/pages/RouteSharedList.js | 57 ++++++++++++++++++++ 8 files changed, 112 insertions(+), 9 deletions(-) create mode 100644 src/pages/RouteSharedList.js diff --git a/src/components/navBar/navBar.js b/src/components/navBar/navBar.js index 3dafd92..d078418 100644 --- a/src/components/navBar/navBar.js +++ b/src/components/navBar/navBar.js @@ -22,6 +22,7 @@ import viadeLogo from './../../assets/logo/logo_alt.jpeg'; import viadeText from './../../assets/logo/logo_letters.jpeg'; import RouteManager from "./../../model/RouteManager"; import ShareView from '../../pages/ShareView'; +import RouteSharedList from "../../pages/RouteSharedList"; const routeManager = RouteManager; @@ -63,6 +64,8 @@ function MyNavBar(props) { {t('navBarMyRoutes')} {t('navBarCreateRoute')} + {t('navBarSharedRoutes')} + {t('navBarRouteHelp')} @@ -87,6 +90,7 @@ function MyNavBar(props) { } /> } /> + } /> } /> } /> diff --git a/src/components/podService/podStoreHandler.js b/src/components/podService/podStoreHandler.js index 30b463d..efd5c18 100644 --- a/src/components/podService/podStoreHandler.js +++ b/src/components/podService/podStoreHandler.js @@ -115,7 +115,6 @@ export default class PodStorageHandler extends PodHandler{ } async getRoutesSharedToMe(forEachRoute = () => {}){ - let result = []; await this._getSharedFolder(async function (file) { // Transform file to JSON let fileAsJSON = JSON.parse(file); @@ -131,11 +130,9 @@ export default class PodStorageHandler extends PodHandler{ let routeObject = new MyRoute(); routeObject.modifyFromJsonLd(JSON.parse(content)); forEachRoute(routeObject); - result.push(routeObject); - }, (error) => {} ); + }, (error) => {forEachRoute(null)} ); } }.bind(this)); - return result; } /** diff --git a/src/components/routeList/RouteCard.js b/src/components/routeList/RouteCard.js index 67f76be..f4c3bc2 100644 --- a/src/components/routeList/RouteCard.js +++ b/src/components/routeList/RouteCard.js @@ -15,9 +15,22 @@ class RouteCard extends React.Component { style={{ borderRadius: "5px", margin: "0", height: "100%", width: "100%" }} /> }; + this.showShareButton = true; + if (props.showShareButton !== undefined) + this.showShareButton = props.showShareButton; + + this.showInfoButton = true; + if (props.showInfoButton !== undefined) + this.showInfoButton = props.showInfoButton; } render() { + + let buttons = [ + this.showInfoButton && , + this.showShareButton && + ]; + return ( @@ -28,8 +41,7 @@ class RouteCard extends React.Component { {this.route.name} {this.route.description} - - + {buttons} ); @@ -39,6 +51,9 @@ class RouteCard extends React.Component { this.setState({ mapComponent: this.state.mapComponent }); } + toggleShareButton(){ + this.showShareButton = !this.showShareButton; + } } diff --git a/src/i18n.js b/src/i18n.js index 6c905c9..4b8fa17 100644 --- a/src/i18n.js +++ b/src/i18n.js @@ -22,6 +22,7 @@ const resources = { "navBarRoutes": "Route management", "navBarMyRoutes": "My routes", "navBarCreateRoute": "Create a new route", + "navBarSharedRoutes" : "Shared to Me", "navBarRouteHelp": "How do routes work?", "routeListText": "Route List", "friendCardDelete": "Delete", @@ -107,6 +108,7 @@ const resources = { "navBarRoutes": "Gestión de rutas", "navBarMyRoutes": "Mis rutas", "navBarCreateRoute": "Crear una nueva ruta", + "navBarSharedRoutes" : "Compartidas conmigo", "navBarRouteHelp": "¿Cómo funcionan las rutas?", "routeListText": "Lista de rutas", "friendCardDelete": "Borrar", diff --git a/src/model/RouteManager.js b/src/model/RouteManager.js index 95ebc62..596377e 100644 --- a/src/model/RouteManager.js +++ b/src/model/RouteManager.js @@ -1,7 +1,7 @@ class RouteManager { constructor() { - this.routes = []; + this.resetRoutes(); } getRoutes() { @@ -16,8 +16,17 @@ class RouteManager { this.routes.push(route); } + addSharedRoute(route){ + this.routesSharedToMe.push(route); + } + + getRouteById(id) { + return this.routesSharedToMe.find((route) => route.getId() === id); + } + resetRoutes() { this.routes = []; + this.routesSharedToMe = []; } } diff --git a/src/pages/Home.js b/src/pages/Home.js index 7d89c0a..53887d9 100644 --- a/src/pages/Home.js +++ b/src/pages/Home.js @@ -35,6 +35,8 @@ class Home extends Component { alt="Viade logo" />

V 1.0

+ + ); diff --git a/src/pages/RouteList.js b/src/pages/RouteList.js index 9aa6015..ffcd802 100644 --- a/src/pages/RouteList.js +++ b/src/pages/RouteList.js @@ -9,6 +9,7 @@ import MyRoute from "../model/MyRoute"; import $ from "jquery"; import 'react-toastify/dist/ReactToastify.css'; +import RouteManager from "../model/RouteManager"; const auth = require('solid-auth-client'); @@ -16,11 +17,12 @@ class RouteList extends React.Component { constructor(props) { super(props); - this.routeManager = props.routeManager; + this.routeManager = RouteManager; this.cardDeckSize = 4; this.state = { routes: [], - spinnerHidden: false + sharedRoutes : [], + spinnerHidden: false, }; this.syncRoutesWithPod().then(() => { this.state.spinnerHidden = true; @@ -74,6 +76,8 @@ class RouteList extends React.Component { let session = await auth.currentSession(); if (session !== null && session !== undefined) { let storageHandler = new PodStorageHandler(session); + + // Handle my Routes storageHandler.getRoutes((routeJson, error) => { if (routeJson === null) { toast.error("We can't access your POD. Please, review its permissions"); @@ -106,6 +110,19 @@ class RouteList extends React.Component { } } ); + + // Handle Shared Routes + storageHandler.getRoutesSharedToMe( (route) => { + if (route === undefined || route == null) { + toast.error("We can't access your POD. Please, review its permissions"); + } else { + this.routeManager.addSharedRoute(route); + let tempList = this.state.sharedRoutes; + tempList.push(route); + this.setState({ sharedRoutes: tempList }); + $("#messageArea").empty(); + } + }); } } diff --git a/src/pages/RouteSharedList.js b/src/pages/RouteSharedList.js new file mode 100644 index 0000000..7c46bfc --- /dev/null +++ b/src/pages/RouteSharedList.js @@ -0,0 +1,57 @@ +import React from "react"; +import RouteManager from "../model/RouteManager"; +import {CardDeck, Spinner} from "react-bootstrap"; +import RouteCard from "../components/routeList/RouteCard"; +import {toast, ToastContainer} from "react-toastify"; +import {Translation} from "react-i18next"; +import PodStorageHandler from "../components/podService/podStoreHandler"; +import MyRoute from "../model/MyRoute"; +import $ from "jquery"; +import RouteList from "./RouteList"; + +export default class RouteSharedList extends RouteList { + + constructor(props) { + super(props); + } + + render() { + let routesForCardDecks = []; + let counter = 0; + while (counter <= this.state.sharedRoutes.length) { + routesForCardDecks.push( + + {this.state.sharedRoutes.slice(counter, counter + this.cardDeckSize).map( + (r) => {return } + )} + + ); + counter += this.cardDeckSize; + } + + return ( +
+ + + { + (t) =>

{t('routeListText')}

+ } +
+ + { + (t) => + } + + +
+ ); + } +} \ No newline at end of file From e783924b2f8b9e0d5c89919d5d4eb18d5f59674d Mon Sep 17 00:00:00 2001 From: jesQM Date: Fri, 24 Apr 2020 09:45:58 +0200 Subject: [PATCH 2/6] Pod modifications to make sure routes are added only once as shared --- src/components/podService/podStoreHandler.js | 62 ++++++++++++++------ 1 file changed, 44 insertions(+), 18 deletions(-) diff --git a/src/components/podService/podStoreHandler.js b/src/components/podService/podStoreHandler.js index efd5c18..df15b08 100644 --- a/src/components/podService/podStoreHandler.js +++ b/src/components/podService/podStoreHandler.js @@ -14,6 +14,7 @@ export default class PodStorageHandler extends PodHandler{ */ constructor(currentSession) { super(currentSession); + this.sharedRoutesToAdd = []; } /** @@ -149,25 +150,22 @@ export default class PodStorageHandler extends PodHandler{ const parser = new N3.Parser(); parser.parse(content, function (error, quad, prefixes) { // parse the content of the message if (quad) { - if ( quad.predicate.id == "http://schema.org/text" ) { // If the quad is the url of the route + if ( quad.predicate.id == "http://schema.org/text" && quad.object.id.includes("/viade/routes/") ) { // If the quad is the url of the route forEachMail(quad.object.id); console.log("PUSHED " + quad.object.id); - //newRoutes.push(quad.object.id); - this.addRoutesAsShared([quad.object.id.split("\"").join("")]); - this._markEmailAsRead(url); + this.sharedRoutesToAdd.push(quad.object.id.split("\"").join("")); } } }.bind(this)); - }.bind(this), - (error) => {} + }.bind(this), + (error) => {} ); }.bind(this)); - //await this.addRoutesAsShared(newRoutes); - }.bind(this), (error) => { } ); + this.addRoutesAsShared(this.sharedRoutesToAdd); } /** @@ -193,6 +191,43 @@ export default class PodStorageHandler extends PodHandler{ async addRoutesAsShared(urls){ console.log("HasBeenShared! " + urls); + let file = null; + let filename = "en3a.json"; + + // 1.- Get a shared File + try { + file = await this.getFile(this.repository + this.defaultFolder + this.sharedDirectory + filename); + file = JSON.parse(file); + } catch (e) { + if (e.status !== 404) { + throw e + } else { + file = { + "@context": { + "@version": 1.1, + "routes": { + "@container": "@list", + "@id": "viade:routes" + }, + "viade": "http://arquisoft.github.io/viadeSpec/" + }, + "routes": [] + } + } + } + + // 2.- Remove duplicated routes + let alreadyRoutes = file["routes"].map((url) => {return url["@id"]}); + console.log(alreadyRoutes); + urls.forEach((url) => { + if (alreadyRoutes.indexOf(url) == -1) { + alreadyRoutes.push( {"@id": url.toString()} ); + } + }); + urls = []; + + // 3.- Rewrite file + file["routes"] = alreadyRoutes; let content = JSON.stringify( { @@ -207,16 +242,7 @@ export default class PodStorageHandler extends PodHandler{ "routes": urls.map((url) => {return {"@id": url.toString()}}) }); - //console.log(urls); - //console.log(urls.map((url) => {return {"@id": url}})); - //console.log(content); - - let filename = Date.now() + ".json"; - this.storeFile(this.repository + this.defaultFolder + this.sharedDirectory + filename, content); - } - - _markEmailAsRead(url) { - //console.log("READ! " + url); + this.storeFile(this.repository + this.defaultFolder + this.sharedDirectory + filename, JSON.stringify(file)); } async getFolder(url) { From 707eabf0057b1c255b8217184a5363538c92d155 Mon Sep 17 00:00:00 2001 From: jesQM Date: Fri, 24 Apr 2020 09:56:14 +0200 Subject: [PATCH 3/6] Removed debug code plus added auto email check --- src/components/podService/podStoreHandler.js | 21 ++------------------ src/pages/Home.js | 15 -------------- src/pages/RouteSharedList.js | 6 ++++++ 3 files changed, 8 insertions(+), 34 deletions(-) diff --git a/src/components/podService/podStoreHandler.js b/src/components/podService/podStoreHandler.js index df15b08..1cff1d6 100644 --- a/src/components/podService/podStoreHandler.js +++ b/src/components/podService/podStoreHandler.js @@ -125,7 +125,6 @@ export default class PodStorageHandler extends PodHandler{ sharedRoutes = sharedRoutes.map((j) => { return j["@id"]; }); for (let i = 0; i < sharedRoutes.length; i++){ let fileUrl = sharedRoutes[i]; - console.log(fileUrl); await this.getFile(fileUrl).then( function(content) { // Create routes from JSON let routeObject = new MyRoute(); @@ -152,7 +151,6 @@ export default class PodStorageHandler extends PodHandler{ if (quad) { if ( quad.predicate.id == "http://schema.org/text" && quad.object.id.includes("/viade/routes/") ) { // If the quad is the url of the route forEachMail(quad.object.id); - console.log("PUSHED " + quad.object.id); this.sharedRoutesToAdd.push(quad.object.id.split("\"").join("")); } } @@ -190,7 +188,6 @@ export default class PodStorageHandler extends PodHandler{ } async addRoutesAsShared(urls){ - console.log("HasBeenShared! " + urls); let file = null; let filename = "en3a.json"; @@ -218,29 +215,15 @@ export default class PodStorageHandler extends PodHandler{ // 2.- Remove duplicated routes let alreadyRoutes = file["routes"].map((url) => {return url["@id"]}); - console.log(alreadyRoutes); urls.forEach((url) => { if (alreadyRoutes.indexOf(url) == -1) { - alreadyRoutes.push( {"@id": url.toString()} ); + alreadyRoutes.push( url ); } }); urls = []; // 3.- Rewrite file - file["routes"] = alreadyRoutes; - - let content = JSON.stringify( - { - "@context": { - "@version": 1.1, - "routes": { - "@container": "@list", - "@id": "viade:routes" - }, - "viade": "http://arquisoft.github.io/viadeSpec/" - }, - "routes": urls.map((url) => {return {"@id": url.toString()}}) - }); + file["routes"] = alreadyRoutes.map((url) => {return {"@id": url.toString()}}); this.storeFile(this.repository + this.defaultFolder + this.sharedDirectory + filename, JSON.stringify(file)); } diff --git a/src/pages/Home.js b/src/pages/Home.js index 53887d9..8e6504a 100644 --- a/src/pages/Home.js +++ b/src/pages/Home.js @@ -35,23 +35,8 @@ class Home extends Component { alt="Viade logo" />

V 1.0

- - ); - - // - // - } - - async getEmail(){ - await new PodStorageHandler(await auth.currentSession()).checkInbox((r) => {}); // console.log("Callback called:"); console.log(r); - } - - async getSharedToMe(){ - let routes = await new PodStorageHandler(await auth.currentSession()).getRoutesSharedToMe((r) => {console.log("Callback called:"); console.log(r);}); - console.log("Function finished"); - console.log(routes); } async printName() { diff --git a/src/pages/RouteSharedList.js b/src/pages/RouteSharedList.js index 7c46bfc..2739199 100644 --- a/src/pages/RouteSharedList.js +++ b/src/pages/RouteSharedList.js @@ -8,11 +8,17 @@ import PodStorageHandler from "../components/podService/podStoreHandler"; import MyRoute from "../model/MyRoute"; import $ from "jquery"; import RouteList from "./RouteList"; +const auth = require('solid-auth-client'); export default class RouteSharedList extends RouteList { constructor(props) { super(props); + this.readInbox(); + } + + async readInbox() { + new PodStorageHandler(await auth.currentSession()).checkInbox(); } render() { From 177db6fcbe82b320575479bc0b1de97e14b57e8d Mon Sep 17 00:00:00 2001 From: jesQM Date: Fri, 24 Apr 2020 10:11:57 +0200 Subject: [PATCH 4/6] Added coverage test --- src/pages/RouteList.js | 12 +++++++----- src/pages/RouteSharedList.js | 3 ++- src/tests/RouteSharedList.test.js | 24 ++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 src/tests/RouteSharedList.test.js diff --git a/src/pages/RouteList.js b/src/pages/RouteList.js index ffcd802..3a204b5 100644 --- a/src/pages/RouteList.js +++ b/src/pages/RouteList.js @@ -24,11 +24,13 @@ class RouteList extends React.Component { sharedRoutes : [], spinnerHidden: false, }; - this.syncRoutesWithPod().then(() => { - this.state.spinnerHidden = true; - }); - this.processedRoutes = 0; - this.retrievedRoutes = 0; + if (props.sync == undefined || props.sync == true) { + this.syncRoutesWithPod().then(() => { + this.state.spinnerHidden = true; + }); + this.processedRoutes = 0; + this.retrievedRoutes = 0; + } } render() { diff --git a/src/pages/RouteSharedList.js b/src/pages/RouteSharedList.js index 2739199..a07bff9 100644 --- a/src/pages/RouteSharedList.js +++ b/src/pages/RouteSharedList.js @@ -14,7 +14,8 @@ export default class RouteSharedList extends RouteList { constructor(props) { super(props); - this.readInbox(); + if (props.sync == undefined || props.sync == true) + this.readInbox(); } async readInbox() { diff --git a/src/tests/RouteSharedList.test.js b/src/tests/RouteSharedList.test.js new file mode 100644 index 0000000..ac2b026 --- /dev/null +++ b/src/tests/RouteSharedList.test.js @@ -0,0 +1,24 @@ +import React from "react"; +import { render } from "@testing-library/react"; +import RouteManager from "./../model/RouteManager"; +import RouteList from "./../pages/RouteList"; +import MyRoute from "../model/MyRoute"; +import RouteSharedList from "../pages/RouteSharedList"; + +const routeManager = RouteManager; + +test("renders learn react link", () => { + const routeManager = RouteManager; + const myRoute = new MyRoute( + "Fuso de la Reina", + "María santísima", + "Easy to complete, mostly straight lines. Concrete does its job turning your knees into dust.", + [{ lat: 2, lng: 4 }, { lat: 24, lng: 13 }], + {} + ); + routeManager.addSharedRoute(myRoute); + + const { getByText } = render(); + const route1 = getByText('routeListText'); + expect(route1).toBeInTheDocument(); +}); \ No newline at end of file From e79c5b82404713af51eff944aa8c50b4a7e53063 Mon Sep 17 00:00:00 2001 From: jesQM Date: Fri, 24 Apr 2020 10:15:41 +0200 Subject: [PATCH 5/6] Bugfix with route manager Duplicated method signature --- src/model/RouteManager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/model/RouteManager.js b/src/model/RouteManager.js index 596377e..d15c66e 100644 --- a/src/model/RouteManager.js +++ b/src/model/RouteManager.js @@ -20,7 +20,7 @@ class RouteManager { this.routesSharedToMe.push(route); } - getRouteById(id) { + getSharedRouteById(id) { return this.routesSharedToMe.find((route) => route.getId() === id); } From 717117af4b59e21b04c47c0933beeae3daa55e65 Mon Sep 17 00:00:00 2001 From: jesQM Date: Fri, 24 Apr 2020 10:20:00 +0200 Subject: [PATCH 6/6] Better code quality --- src/components/podService/podStoreHandler.js | 12 ++++++------ src/components/routeList/RouteCard.js | 6 ++++-- src/pages/RouteSharedList.js | 4 ++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/components/podService/podStoreHandler.js b/src/components/podService/podStoreHandler.js index 1cff1d6..a81fe06 100644 --- a/src/components/podService/podStoreHandler.js +++ b/src/components/podService/podStoreHandler.js @@ -130,7 +130,7 @@ export default class PodStorageHandler extends PodHandler{ let routeObject = new MyRoute(); routeObject.modifyFromJsonLd(JSON.parse(content)); forEachRoute(routeObject); - }, (error) => {forEachRoute(null)} ); + }, (error) => {forEachRoute(null);} ); } }.bind(this)); } @@ -149,7 +149,7 @@ export default class PodStorageHandler extends PodHandler{ const parser = new N3.Parser(); parser.parse(content, function (error, quad, prefixes) { // parse the content of the message if (quad) { - if ( quad.predicate.id == "http://schema.org/text" && quad.object.id.includes("/viade/routes/") ) { // If the quad is the url of the route + if ( quad.predicate.id === "http://schema.org/text" && quad.object.id.includes("/viade/routes/") ) { // If the quad is the url of the route forEachMail(quad.object.id); this.sharedRoutesToAdd.push(quad.object.id.split("\"").join("")); } @@ -197,7 +197,7 @@ export default class PodStorageHandler extends PodHandler{ file = JSON.parse(file); } catch (e) { if (e.status !== 404) { - throw e + throw e; } else { file = { "@context": { @@ -209,14 +209,14 @@ export default class PodStorageHandler extends PodHandler{ "viade": "http://arquisoft.github.io/viadeSpec/" }, "routes": [] - } + }; } } // 2.- Remove duplicated routes - let alreadyRoutes = file["routes"].map((url) => {return url["@id"]}); + let alreadyRoutes = file["routes"].map((url) => {return url["@id"];}); urls.forEach((url) => { - if (alreadyRoutes.indexOf(url) == -1) { + if (alreadyRoutes.indexOf(url) === -1) { alreadyRoutes.push( url ); } }); diff --git a/src/components/routeList/RouteCard.js b/src/components/routeList/RouteCard.js index f4c3bc2..c670cb5 100644 --- a/src/components/routeList/RouteCard.js +++ b/src/components/routeList/RouteCard.js @@ -16,12 +16,14 @@ class RouteCard extends React.Component { /> }; this.showShareButton = true; - if (props.showShareButton !== undefined) + if (props.showShareButton !== undefined) { this.showShareButton = props.showShareButton; + } this.showInfoButton = true; - if (props.showInfoButton !== undefined) + if (props.showInfoButton !== undefined) { this.showInfoButton = props.showInfoButton; + } } render() { diff --git a/src/pages/RouteSharedList.js b/src/pages/RouteSharedList.js index a07bff9..5854744 100644 --- a/src/pages/RouteSharedList.js +++ b/src/pages/RouteSharedList.js @@ -14,7 +14,7 @@ export default class RouteSharedList extends RouteList { constructor(props) { super(props); - if (props.sync == undefined || props.sync == true) + if (props.sync === undefined || props.sync == true) this.readInbox(); } @@ -29,7 +29,7 @@ export default class RouteSharedList extends RouteList { routesForCardDecks.push( {this.state.sharedRoutes.slice(counter, counter + this.cardDeckSize).map( - (r) => {return } + (r) => {return ;} )} );