feat: improve devMode to have hidden menu items

This commit is contained in:
sethburkart123
2024-07-02 21:50:22 +10:00
parent 6c7342400e
commit 74933a778c
5 changed files with 77 additions and 48 deletions
+1 -1
View File
@@ -85,7 +85,7 @@ const TabbedContainer: React.FC<TabbedContainerProps> = ({ tabs }) => {
className='flex' className='flex'
> >
{tabs.map((tab, index) => ( {tabs.map((tab, index) => (
<div key={index} className={`absolute h-[100vh] overflow-y-scroll w-full pb-40 transition-opacity duration-300 ${activeTab === index ? 'opacity-100' : 'opacity-0'}`} <div key={index} className={`absolute h-[100vh] focus-visible:outline-none overflow-y-scroll w-full pb-40 transition-opacity duration-300 ${activeTab === index ? 'opacity-100' : 'opacity-0'}`}
style={{left: `${index * 100}%`}}> style={{left: `${index * 100}%`}}>
{tab.content} {tab.content}
</div> </div>
+4 -4
View File
@@ -27,11 +27,11 @@ const useSettingsState = ({ settingsState, setSettingsState }: SettingsProps) =>
selectedTheme: result.selectedTheme, selectedTheme: result.selectedTheme,
timeFormat: result.timeFormat, timeFormat: result.timeFormat,
animations: result.animations, animations: result.animations,
defaultPage: result.defaultPage defaultPage: result.defaultPage,
devMode: result.devMode || false
}); });
}); });
}); });
const keyToStateMap = useMemo(() => ({ const keyToStateMap = useMemo(() => ({
"notificationcollector": "notificationCollector", "notificationcollector": "notificationCollector",
"lessonalert": "lessonAlerts", "lessonalert": "lessonAlerts",
@@ -45,12 +45,12 @@ const useSettingsState = ({ settingsState, setSettingsState }: SettingsProps) =>
"selectedTheme": "selectedTheme", "selectedTheme": "selectedTheme",
"timeFormat": "timeFormat", "timeFormat": "timeFormat",
"animations": "animations", "animations": "animations",
"defaultPage": "defaultPage" "defaultPage": "defaultPage",
"devMode": "devMode"
}), []); }), []);
const storageChangeListener = (changes: browser.Storage.StorageChange) => { const storageChangeListener = (changes: browser.Storage.StorageChange) => {
for (const [key, { newValue }] of Object.entries(changes)) { for (const [key, { newValue }] of Object.entries(changes)) {
console.log(key, newValue)
if (key === "DarkMode") { if (key === "DarkMode") {
if (key === "DarkMode" && newValue) { if (key === "DarkMode" && newValue) {
document.body.classList.add('dark'); document.body.classList.add('dark');
+66 -39
View File
@@ -1,67 +1,75 @@
import Switch from '../../components/Switch'; import Switch from '../../components/Switch';
import Slider from '../../components/Slider'; import Slider from '../../components/Slider';
import PickerSwatch from '../../components/PickerSwatch'; import PickerSwatch from '../../components/PickerSwatch';
import Select from '../../components/Select';
import { SettingsList } from '../../types/SettingsProps'; import { SettingsList } from '../../types/SettingsProps';
import { useSettingsContext } from '../../SettingsContext'; import { useSettingsContext } from '../../SettingsContext';
import browser from 'webextension-polyfill' import browser from 'webextension-polyfill';
import { memo, useState } from 'react'; import { memo, useCallback } from 'react';
import { toast } from 'react-toastify';
import Select from '../../components/Select';
const Settings: React.FC = () => { const Settings: React.FC = () => {
const { settingsState, setSettingsState } = useSettingsContext(); const { settingsState, setSettingsState } = useSettingsContext();
const [inputSequence, setInputSequence] = useState('');
const [devMode, setDevMode] = useState(false);
const handleSequenceClick = () => { const handleDevModeToggle = useCallback(() => {
setInputSequence(''); // Reset sequence on logo click const secretSequence = 'dev';
document.addEventListener('keydown', handleKeyDown); let typedSequence = '';
}; let timeoutId: NodeJS.Timeout;
const handleKeyDown = (event: KeyboardEvent) => { const handleKeyDown = (event: KeyboardEvent) => {
setInputSequence((prevSequence) => { typedSequence += event.key.toLowerCase();
const newSequence = prevSequence + event.key.toLowerCase();
if (newSequence.includes('dev')) { if (typedSequence.includes(secretSequence)) {
document.removeEventListener('keydown', handleKeyDown); document.removeEventListener('keydown', handleKeyDown);
toast.success('Dev mode enabled!'); clearTimeout(timeoutId);
setInputSequence('');
setDevMode(true); setSettingsState(prevState => ({
...prevState,
devMode: !prevState.devMode
}));
alert(`Dev mode is now ${!settingsState.devMode ? 'enabled' : 'disabled'}`);
} }
return newSequence;
}); // Clear the sequence after 2 seconds of inactivity
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
typedSequence = '';
}, 2000);
}; };
const switchChange = (key: string, value: boolean | string) => { document.addEventListener('keydown', handleKeyDown);
setSettingsState({
...settingsState,
[key]: value,
});
};
const sliderChange = (key: string, value: number) => { // Cleanup function to remove the event listener
setSettingsState({ return () => {
...settingsState, document.removeEventListener('keydown', handleKeyDown);
[key]: value, clearTimeout(timeoutId);
});
}; };
}, [setSettingsState, settingsState.devMode]);
const handleSettingChange = useCallback((key: string, value: boolean | string | number) => {
setSettingsState(prevState => ({
...prevState,
[key]: value,
}));
}, [setSettingsState]);
const settings: SettingsList[] = [ const settings: SettingsList[] = [
{ {
title: "Transparency Effects", title: "Transparency Effects",
description: "Enables transparency effects on certain elements such as blur. (May impact battery life)", description: "Enables transparency effects on certain elements such as blur. (May impact battery life)",
modifyElement: <Switch state={settingsState.transparencyEffects} onChange={(isOn: boolean) => switchChange('transparencyEffects', isOn)} /> modifyElement: <Switch state={settingsState.transparencyEffects} onChange={(isOn: boolean) => handleSettingChange('transparencyEffects', isOn)} />
}, },
{ {
title: "Animated Background", title: "Animated Background",
description: "Adds an animated background to BetterSEQTA. (May impact battery life)", description: "Adds an animated background to BetterSEQTA. (May impact battery life)",
modifyElement: <Switch state={settingsState.animatedBackground} onChange={(isOn: boolean) => switchChange('animatedBackground', isOn)} /> modifyElement: <Switch state={settingsState.animatedBackground} onChange={(isOn: boolean) => handleSettingChange('animatedBackground', isOn)} />
}, },
{ {
title: "Animated Background Speed", title: "Animated Background Speed",
description: "Controls the speed of the animated background.", description: "Controls the speed of the animated background.",
modifyElement: <Slider state={parseInt(settingsState.animatedBackgroundSpeed)} onChange={(value: number) => sliderChange('animatedBackgroundSpeed', value)} /> modifyElement: <Slider state={parseInt(settingsState.animatedBackgroundSpeed)} onChange={(value: number) => handleSettingChange('animatedBackgroundSpeed', value)} />
}, },
{ {
title: "Custom Theme Colour", title: "Custom Theme Colour",
@@ -76,27 +84,27 @@ const Settings: React.FC = () => {
{ {
title: "Animations", title: "Animations",
description: "Enables animations on certain pages.", description: "Enables animations on certain pages.",
modifyElement: <Switch state={settingsState.animations} onChange={(isOn: boolean) => switchChange('animations', isOn)} /> modifyElement: <Switch state={settingsState.animations} onChange={(isOn: boolean) => handleSettingChange('animations', isOn)} />
}, },
{ {
title: "Notification Collector", title: "Notification Collector",
description: "Uncaps the 9+ limit for notifications, showing the real number.", description: "Uncaps the 9+ limit for notifications, showing the real number.",
modifyElement: <Switch state={settingsState.notificationCollector} onChange={(isOn: boolean) => switchChange('notificationCollector', isOn)} /> modifyElement: <Switch state={settingsState.notificationCollector} onChange={(isOn: boolean) => handleSettingChange('notificationCollector', isOn)} />
}, },
{ {
title: "Lesson Alerts", title: "Lesson Alerts",
description: "Sends a native browser notification ~5 minutes prior to lessons.", description: "Sends a native browser notification ~5 minutes prior to lessons.",
modifyElement: <Switch state={settingsState.lessonAlerts} onChange={(isOn: boolean) => switchChange('lessonAlerts', isOn)} /> modifyElement: <Switch state={settingsState.lessonAlerts} onChange={(isOn: boolean) => handleSettingChange('lessonAlerts', isOn)} />
}, },
{ {
title: "12 Hour Time", title: "12 Hour Time",
description: "Prefer 12 hour time format for SEQTA", description: "Prefer 12 hour time format for SEQTA",
modifyElement: <Switch state={settingsState.timeFormat == "12"} onChange={(isOn: boolean) => switchChange('timeFormat', isOn ? "12" : "24")} /> modifyElement: <Switch state={settingsState.timeFormat == "12"} onChange={(isOn: boolean) => handleSettingChange('timeFormat', isOn ? "12" : "24")} />
}, },
{ {
title: "Default Page", title: "Default Page",
description: "The page to load when SEQTA Learn is opened.", description: "The page to load when SEQTA Learn is opened.",
modifyElement: <Select state={settingsState.defaultPage} onChange={(value: string) => switchChange('defaultPage', value)} options={[ modifyElement: <Select state={settingsState.defaultPage} onChange={(value: string) => handleSettingChange('defaultPage', value)} options={[
{ value: 'home', label: 'Home' }, { value: 'home', label: 'Home' },
{ value: 'dashboard', label: 'Dashboard' }, { value: 'dashboard', label: 'Dashboard' },
{ value: 'timetable', label: 'Timetable' }, { value: 'timetable', label: 'Timetable' },
@@ -109,7 +117,7 @@ const Settings: React.FC = () => {
{ {
title: "BetterSEQTA+", title: "BetterSEQTA+",
description: "Enables BetterSEQTA+ features", description: "Enables BetterSEQTA+ features",
modifyElement: <Switch state={settingsState.betterSEQTAPlus} onChange={(isOn: boolean) => switchChange('betterSEQTAPlus', isOn)} /> modifyElement: <Switch state={settingsState.betterSEQTAPlus} onChange={(isOn: boolean) => handleSettingChange('betterSEQTAPlus', isOn)} />
} }
]; ];
@@ -118,7 +126,7 @@ const Settings: React.FC = () => {
{settings.map((setting, index) => ( {settings.map((setting, index) => (
<div className="flex items-center justify-between px-4 py-3" key={index}> <div className="flex items-center justify-between px-4 py-3" key={index}>
<div className="pr-4"> <div className="pr-4">
<h2 {...(setting.title.includes('BetterSEQTA+') ? { onClick: handleSequenceClick } : {})} className="text-sm font-bold">{setting.title}</h2> <h2 onClick={setting.title.includes('BetterSEQTA+') ? handleDevModeToggle : undefined} className="text-sm font-bold">{setting.title}</h2>
<p className="text-xs">{setting.description}</p> <p className="text-xs">{setting.description}</p>
</div> </div>
<div> <div>
@@ -126,6 +134,25 @@ const Settings: React.FC = () => {
</div> </div>
</div> </div>
))} ))}
{settingsState.devMode && (
<>
<div className="flex items-center justify-between px-4 py-3">
<div className="pr-4">
<h2 className="text-sm font-bold">Dev Mode</h2>
<p className="text-xs">Enables dev mode</p>
</div>
<Switch state={settingsState.devMode} onChange={(isOn: boolean) => handleSettingChange('devMode', isOn)} />
</div>
<div className="flex items-center justify-between px-4 py-3">
<div className="pr-4">
<h2 className="text-sm font-bold">Sensitive Hider</h2>
<p className="text-xs">Replace sensitive content with mock data</p>
</div>
<button onClick={() => browser.runtime.sendMessage({ type: 'currentTab', info: 'HideSensitive' })} className='px-4 py-1 text-[0.75rem] dark:bg-[#38373D] bg-[#DDDDDD] dark:text-white rounded-md'>Hide</button>
</div>
</>
)}
</div> </div>
); );
}; };
+1
View File
@@ -12,6 +12,7 @@ export interface SettingsState {
timeFormat?: string; timeFormat?: string;
animations: boolean; animations: boolean;
defaultPage: string; defaultPage: string;
devMode: boolean;
} }
interface Shortcut { interface Shortcut {
+1
View File
@@ -36,6 +36,7 @@ export interface SettingsState {
timeFormat?: string; timeFormat?: string;
animations: boolean; animations: boolean;
defaultPage: string; defaultPage: string;
devMode?: boolean;
} }
interface ToggleItem { interface ToggleItem {