src/components/presenters/bikedetails-presenter.js
import BasePresenter from './presenter';
import { HomeM, MapM, AlertM } from '../models/export-models';
import ImageUtil from '../../util/imageutility';
const NO_DATA = 'NO-DATA';
/**
* Class for the BikeDetails presenter and view
* @extends BasePresenter
*/
class BikeDetailsPresenter extends BasePresenter {
/**
* Creates an instance of BikeDetailsPresenter
*
* @constructor
* @param {Object} view - An instance of a view class
*/
constructor(view) {
super();
this.view = view;
HomeM.subscribe(this);
}
/**
* If the view or presenter is destroyed, unsubscribe the presenter from the model.
*/
onDestroy = () => {
HomeM.unsubscribe(this);
};
/**
* Updates the bike model with new data.
*
* @param {Object} newData - New data to update the model's data with.
*/
update = (newData) => {
// HomeM.update(newData);
}
/**
* Called when the model is updated with new data. Refreshes the state of the view.
* Method is supplied with the data to add.
* Better way to refresh the state?
*
* @param {Object} newData - New data to add.
*/
onUpdated = (newData) => {
// Do something with the new data or let the view auto update?
// console.log(newData)
this.view.refreshState();
};
/**
* Gets the data from the model and returns it to the caller.
*
* @return {Object} Data from the model.
*/
getData = () => {
// return HomeM.get().data;
};
/**
* Translates the data from a list of objects to a title and text with an id.
*
* @param {Object} data - The data to be translated
* @return {List, List} An object with two lists. 1. The formed data; 2. The list of thumbnails
*/
translateData = (data, fromPage) => {
let formedData = [];
// console.log(data);
Object.keys(data).forEach((key,index) => {
if (this.getIgnoredDetails().includes(key.toString())) { // Ignore any keys defined in getIgnoredDetails
return; // Acts as continue in 'forEach'
// Don't show lost description on alerts page and found_description on home page
} else if ((key === 'description' && fromPage === 'Alerts') || (key === 'found_description' && fromPage === 'Home')) {
return;
}
let keyStr = (key.toString()).replace('_', ' ');
keyStr = this.convertCase(keyStr);
// Build the object
// id must be unique
// title is the text input label
const translated = {
title: keyStr + ": ",
text: Array.isArray(data[key]) ? data[key].join(', ') : data[key],
id: index.toString()
};
formedData.push(translated);
});
// Need to form the thumbnail properly because it's just a link right now
let thumbnail = ImageUtil.formThumbnail(data.thumbnail);
formedData = this.reorderData(formedData);
// console.log(formedData, thumbnail);
return { formedData, thumbnail };
}
/**
* Reorders the data to be based on a specific order defined in getDetailsOrder.
*
* @param {List} data - The data to be reordered
* @return {List} The reordered data
*/
reorderData = (data) => {
let orderedData = [];
const order = this.getDetailsOrder();
for (let i=0; i < order.length; i++) {
const found_element = this.findElement(data, order[i]);
// If the element exists and was defined in the data, then add it, otherwise ignore it
if (found_element != undefined && found_element.text !== '') {
orderedData.push(found_element);
}
}
return orderedData;
}
/**
* Finds if an element exists with a specific title based on a key.
*
* @param {List} data - Data to find an element in
* @param {string} key - A key to look for
* @return {Object} The first element found since data titles should be unique anyway
*/
findElement = (data, key) => {
return data.filter(el => {
return el.title === key + ": ";
})[0]; // Takes the first element because keys should be unique so just to be safe
}
/**
* Convert the case of a string to title case (first letter of each word is uppercase).
*
* @param {string} str - A string to convert
* @return {string} The string converted to title case
*/
convertCase = (str) => {
return str == undefined || str == null ? '' : str.toLowerCase().replace(/(^| )(\w)/g, s => s.toUpperCase()); // Regex FTW
}
/**
* Returns the order of the details as a list. List will appear in this order.
* Keys should be defined as the property name replacing all underscores with spaces then converted to title case (Does not include ': ').
*
* @return {List} A list of title case key names in the order that is needed
*/
getDetailsOrder = () => {
return ["Name", "Serial Number", "Timeago", "Datetime", "Model", "Brand", "Colour", "Frame Size", "Wheel Size", "Notable Features", "Description", "Found Description"];
}
/**
* Ignore this list of properties when transforming data objects to formed data.
*
* @return {List} A list of string properties to ignore
*/
getIgnoredDetails = () => {
return ['id', 'owner', 'thumbnail', 'dataID', 'milliseconds'];
}
/**
* Asks the model to open the prompt to open directions.
*
* @param {Object} data - The data of where to go to. Must include longitude and latitude
* @param {Function} onError - A function callback if there is an error with the data
*/
goToDirectionsOnMap = (data, onError) => {
if (!data.hasOwnProperty('longitude') && !data.hasOwnProperty('latitude')) {
onError();
return;
}
const location = {
longitude: data.longitude,
latitude: data.latitude
};
MapM.showMaps(location);
}
confirmFound(rawData,callback){
const newBike = {data:{}};
Object.keys(rawData).forEach((key) => {
// console.log(key)
newBike.data[key] = rawData[key];
});
// console.log(newBike.data.id);
newBike.data.found = false;
newBike.data.stolen = false;
newBike.data.found_description = '';
newBike.data.found_latitude = '';
newBike.data.found_longitude = '';
newBike.data.found_milliseconds = '';
newBike.data.latitude = '';
newBike.data.longitude = '';
newBike.data.milliseconds = '';
AlertM.setCallback(callback);
AlertM.update(newBike.data);
}
rejectFound(rawData,callback){
const newBike = {data:{}};
Object.keys(rawData).forEach((key) => {
// console.log(key)
newBike.data[key] = rawData[key];
});
// console.log(newBike.data.id);
newBike.data.found = false;
newBike.data.stolen = true;
AlertM.setCallback(callback);
AlertM.update(newBike.data);
}
getDataFromID(id){
let dataList = HomeM.get().data;
// console.log(dataList);
for (let i = 0; i < dataList.length; i ++ ){
if(dataList[i].id == id){
// console.log('i found id');
return dataList[i];
}
}
return 'NO-DATA';
}
}
export default BikeDetailsPresenter