Merge branch 'main' into sgunter/feat-preserve-email-on-feedback-form
This commit is contained in:
0
docs/WebSocket-Implementation-Tutorial.md
Normal file
0
docs/WebSocket-Implementation-Tutorial.md
Normal file
@@ -1,6 +1,7 @@
|
||||
import CourseCatalogMain from '@views/components/CourseCatalogMain';
|
||||
import InjectedButton from '@views/components/injected/AddAllButton';
|
||||
import DaysCheckbox from '@views/components/injected/DaysCheckbox';
|
||||
import ShadedResults from '@views/components/injected/SearchResultShader';
|
||||
import getSiteSupport, { SiteSupport } from '@views/lib/getSiteSupport';
|
||||
import React from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
@@ -30,3 +31,7 @@ if (support === SiteSupport.MY_UT) {
|
||||
if (support === SiteSupport.COURSE_CATALOG_SEARCH) {
|
||||
renderComponent(DaysCheckbox);
|
||||
}
|
||||
|
||||
if (support === SiteSupport.COURSE_CATALOG_KWS) {
|
||||
renderComponent(ShadedResults);
|
||||
}
|
||||
|
||||
@@ -27,12 +27,10 @@ export default function HexColorEditor({ hexCode, setHexCode }: HexColorEditorPr
|
||||
const tagColor = pickFontColor(previewColor.slice(1) as `#${string}`);
|
||||
|
||||
const [localHexCode, setLocalHexCode] = React.useState(hexCode);
|
||||
const debouncedSetHexCode = useDebounce((value: string) => setHexCode(value), 500);
|
||||
const debouncedSetHexCode = useDebounce(setHexCode, 500);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (hexCode !== localHexCode) {
|
||||
setLocalHexCode(hexCode);
|
||||
}
|
||||
setLocalHexCode(hexCode);
|
||||
}, [hexCode]);
|
||||
|
||||
React.useEffect(() => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { AppStoreLogo, ForkKnife, X as CloseIcon } from '@phosphor-icons/react';
|
||||
import { UT_DINING_APP_STORE_URL, UT_DINING_GOOGLE_PLAY_URL } from '@shared/util/appUrls';
|
||||
import { UT_DINING_APP_STORE_URL } from '@shared/util/appUrls';
|
||||
import { Button } from '@views/components/common/Button';
|
||||
import Text from '@views/components/common/Text/Text';
|
||||
import React from 'react';
|
||||
|
||||
@@ -15,7 +15,7 @@ import React, { useEffect, useState } from 'react';
|
||||
*/
|
||||
const WHATSNEW_POPUP_VERSION = 2;
|
||||
|
||||
const WHATSNEW_VIDEO_URL = 'https://cdn.longhorns.dev/whats-new-v2.1.2.mp4';
|
||||
// const WHATSNEW_VIDEO_URL = 'https://cdn.longhorns.dev/whats-new-v2.1.2.mp4';
|
||||
|
||||
type Feature = {
|
||||
id: string;
|
||||
@@ -60,7 +60,7 @@ const NEW_FEATURES = [
|
||||
* @returns A JSX of WhatsNewPopupContent component.
|
||||
*/
|
||||
export default function WhatsNewPopupContent(): JSX.Element {
|
||||
const [videoError, setVideoError] = useState(false);
|
||||
const [videoError, _setVideoError] = useState(false);
|
||||
|
||||
return (
|
||||
<div className='w-full flex flex-row justify-between'>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { addCourseByURL } from '@pages/background/lib/addCourseByURL';
|
||||
import { background } from '@shared/messages';
|
||||
import { validateLoginStatus } from '@shared/util/checkLoginStatus';
|
||||
import { Button } from '@views/components/common/Button';
|
||||
import ExtensionRoot from '@views/components/common/ExtensionRoot/ExtensionRoot';
|
||||
import useSchedules from '@views/hooks/useSchedules';
|
||||
@@ -43,6 +42,8 @@ export default function InjectedButton(): JSX.Element | null {
|
||||
await addCourseByURL(activeSchedule, a);
|
||||
}
|
||||
} else {
|
||||
// We'll allow the alert for this WIP feature
|
||||
// eslint-disable-next-line no-alert
|
||||
window.alert('Logged into UT Registrar.');
|
||||
}
|
||||
};
|
||||
|
||||
39
src/views/components/injected/SearchResultShader.tsx
Normal file
39
src/views/components/injected/SearchResultShader.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
import { useEffect } from 'react';
|
||||
// @TODO Get a better name for this class
|
||||
|
||||
/**
|
||||
* The existing search results (kws), only with alternate shading for easier readability
|
||||
*
|
||||
*/
|
||||
export default function ShadedResults(): null {
|
||||
useEffect(() => {
|
||||
const table = document.getElementById('kw_results_table');
|
||||
if (!table) {
|
||||
console.error('Results table not found');
|
||||
return;
|
||||
}
|
||||
|
||||
const tbody = table.querySelector('tbody');
|
||||
if (!tbody) {
|
||||
console.error('Table tbody not found');
|
||||
return;
|
||||
}
|
||||
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
#kw_results_table tbody tr:nth-child(even) {
|
||||
background-color: #f0f0f0 !important;
|
||||
}
|
||||
#kw_results_table tbody tr:nth-child(even) td {
|
||||
background-color: #f0f0f0 !important;
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
|
||||
return () => {
|
||||
style.remove();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -1,16 +1,13 @@
|
||||
// import addCourse from '@pages/background/lib/addCourse';
|
||||
import { addCourseByURL } from '@pages/background/lib/addCourseByURL';
|
||||
import { deleteAllSchedules } from '@pages/background/lib/deleteSchedule';
|
||||
import exportSchedule from '@pages/background/lib/exportSchedule';
|
||||
import importSchedule from '@pages/background/lib/importSchedule';
|
||||
import { CalendarDots, Trash } from '@phosphor-icons/react';
|
||||
import { background } from '@shared/messages';
|
||||
import { DevStore } from '@shared/storage/DevStore';
|
||||
import { initSettings, OptionsStore } from '@shared/storage/OptionsStore';
|
||||
import { UserScheduleStore } from '@shared/storage/UserScheduleStore';
|
||||
import { CRX_PAGES } from '@shared/types/CRXPages';
|
||||
import MIMEType from '@shared/types/MIMEType';
|
||||
import { downloadBlob } from '@shared/util/downloadBlob';
|
||||
// import { addCourseByUrl } from '@shared/util/courseUtils';
|
||||
// import { getCourseColors } from '@shared/util/colors';
|
||||
// import CalendarCourseCell from '@views/components/calendar/CalendarCourseCell';
|
||||
|
||||
@@ -5,8 +5,7 @@ import WhatsNewPopupContent from '@views/components/common/WhatsNewPopup';
|
||||
import { useDialog } from '@views/contexts/DialogContext';
|
||||
import React from 'react';
|
||||
|
||||
import { LogoIcon } from '../components/common/LogoIcon';
|
||||
import useChangelog from './useChangelog';
|
||||
// import useChangelog from './useChangelog';
|
||||
|
||||
const LDIconURL = new URL('/src/assets/LD-icon-new.png', import.meta.url).href;
|
||||
|
||||
@@ -17,8 +16,8 @@ const LDIconURL = new URL('/src/assets/LD-icon-new.png', import.meta.url).href;
|
||||
*/
|
||||
export default function useWhatsNewPopUp(): () => void {
|
||||
const showDialog = useDialog();
|
||||
const showChangeLog = useChangelog();
|
||||
const { version } = chrome.runtime.getManifest();
|
||||
// const showChangeLog = useChangelog();
|
||||
// const { version } = chrome.runtime.getManifest();
|
||||
|
||||
const showPopUp = () => {
|
||||
showDialog(close => ({
|
||||
|
||||
@@ -15,6 +15,7 @@ export const SiteSupport = {
|
||||
MY_UT: 'MY_UT',
|
||||
COURSE_CATALOG_SEARCH: 'COURSE_CATALOG_SEARCH',
|
||||
CLASSLIST: 'CLASSLIST',
|
||||
COURSE_CATALOG_KWS: 'COURSE_CATALOG_KWS',
|
||||
} as const;
|
||||
|
||||
/**
|
||||
@@ -40,6 +41,9 @@ export default function getSiteSupport(url: string): SiteSupportType | null {
|
||||
return SiteSupport.UT_PLANNER;
|
||||
}
|
||||
if (url.includes('utdirect.utexas.edu/apps/registrar/course_schedule')) {
|
||||
if (url.includes('kws_results')) {
|
||||
return SiteSupport.COURSE_CATALOG_KWS;
|
||||
}
|
||||
if (url.includes('results')) {
|
||||
return SiteSupport.COURSE_CATALOG_LIST;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user