You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

149 lines
4.3 KiB

import React, { useState } from "react";
import { Tabs, Tab } from "react-tabs-scrollable";
import "react-tabs-scrollable/dist/rts.css";
import { getHeatmapData } from "./webpage_container/StudySite";
import { pushToMouseLog } from "../core/log/SensorLogger";
import {
playTabEarconSonification,
playTabModelSonification,
} from "../core/audio/AudioHandler";
import { Divider } from "@geist-ui/core";
var reachedEndValue = false;
var rightSideEnd = true;
var endElement = 0;
var type = "";
function ScrollableTab({ onActiveTabChange, sonificationType, children }) {
const [activeTab, setActiveTab] = useState(0);
const [amountTabs, setAmountTabs] = useState(children.length);
endElement = amountTabs;
type = sonificationType;
const saveMouseLog = function () {
pushToMouseLog(getHeatmapData());
};
// define a onClick function to bind the value on tab click
const onTabClick = (e, index) => {
const buttonAttributes = e.target.attributes;
const actionType = buttonAttributes["actionType"]
? buttonAttributes.getNamedItem("actionType").value
: "";
const redirectLoc = buttonAttributes["redirectLoc"]
? buttonAttributes.getNamedItem("redirectLoc").value
: "";
if (actionType === "button") {
saveMouseLog();
window.location.href = redirectLoc;
}
setActiveTab(index);
onActiveTabChange(index);
};
const onHoverElement = () => {};
const onHoverTab = (key) => {
const clamp = (num, min, max) => Math.min(Math.max(num, min), max);
const panVal = rightSideEnd
? clamp(3 * ((-1 / amountTabs) * key + 1) - 2, -1, 1)
: clamp(2 * ((-1 / amountTabs) * -1 * key + 1) - 4, -1, 1); // ((-1 / amountTabs) * key + 1);
const frequencyVal = rightSideEnd
? Math.round((key / amountTabs) * key + 6)
: Math.round(((key - amountTabs) / amountTabs) * (key - amountTabs) + 6);
var endValueVisible = isVisible(document.getElementById(endElement));
if (endValueVisible) {
reachedEndValue = true;
}
if (type === "model") {
playTabModelSonification(panVal, frequencyVal, !rightSideEnd);
} else if (type === "earcon") {
playTabEarconSonification(!rightSideEnd, key, amountTabs);
}
if (reachedEndValue && endValueVisible) {
// Chord End sound play... :)
if (rightSideEnd) {
endElement = 1;
rightSideEnd = false;
} else {
endElement = amountTabs;
rightSideEnd = true;
}
} else if (!endValueVisible) {
//this.playChordSound(panVal, frequencyVal);
//this.playPitchSound(panVal, 200 + 10*key);
}
};
// didReachEnd is bad... That is why, I have my own function... :)
// This sets it to "visible", if at least some part is visible... But maybe I want to have a percentage-based thing...
// If whole viewport is necessary, this makes it also bad, since a scroll all the way is required...
// Not really necessary, since the user already "knows", that this is the end...
const isVisible = (el) => {
var rect = el.getBoundingClientRect();
return (
rect.bottom > 0 &&
rect.right > 0 &&
rect.left < (window.innerWidth || document.documentElement.clientWidth) &&
rect.top < (window.innerHeight || document.documentElement.clientHeight)
);
};
//var keys = Array.from({ length: amountTabs }, (_, i) => i + 1);
// onFocus as an additional thingy?
var tabId = 0;
var tabs = children.map((k) => {
tabId += 1;
return (
<Tab
id={tabId}
//onTouchMove={() => onHoverTab(tabId)}
//onMouseOver={() => onHoverTab(tabId)}
key={tabId}
actionType={k.props.actionType}
redirectLoc={k.props.redirectLoc}
>
{k.props.children}
</Tab>
);
});
const tabsStyle = {
position: "fixed",
bottom: "0",
width: "100vw",
zIndex: "998",
backgroundColor: "white",
};
return (
<div
style={tabsStyle}
onClick={() => {}}
onTouchStart={(event) => {
const eventElement = event.target;
if (eventElement.nodeName === "BUTTON") {
onHoverTab(eventElement.id);
}
}}
>
<Divider />
<Tabs
onMouseOver={() => onHoverElement()}
activeTab={activeTab}
onTabClick={(e, index) => onTabClick(e, index)}
>
{tabs}
</Tabs>
</div>
);
}
export default ScrollableTab;