analyzing page types and populating search inputs
This commit is contained in:
@@ -32,6 +32,7 @@ export async function hotReloadTab(): Promise<void> {
|
|||||||
|
|
||||||
chrome.tabs.get(reloadTabId, tab => {
|
chrome.tabs.get(reloadTabId, tab => {
|
||||||
if (!tab?.id) return;
|
if (!tab?.id) return;
|
||||||
|
if (!tab.url) return;
|
||||||
if (!HOT_RELOADING_WHITELIST.find(url => tab.url?.includes(url))) {
|
if (!HOT_RELOADING_WHITELIST.find(url => tab.url?.includes(url))) {
|
||||||
chrome.tabs.reload(tab.id);
|
chrome.tabs.reload(tab.id);
|
||||||
}
|
}
|
||||||
|
|||||||
16
src/shared/storage/optionsStore.ts
Normal file
16
src/shared/storage/optionsStore.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { createStore } from 'chrome-extension-toolkit';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A store that is used for storing user options
|
||||||
|
*/
|
||||||
|
interface IOptionsStore {
|
||||||
|
/** whether we should automatically highlight conflicts on the course schedule page */
|
||||||
|
shouldHighlightConflicts: boolean;
|
||||||
|
/** whether we should automatically scroll to load more courses on the course schedule page (without having to click next) */
|
||||||
|
shouldScrollToLoad: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const optionsStore = createStore<IOptionsStore>('OPTIONS_STORE', {
|
||||||
|
shouldHighlightConflicts: true,
|
||||||
|
shouldScrollToLoad: true,
|
||||||
|
});
|
||||||
@@ -3,22 +3,27 @@ import { render } from 'react-dom';
|
|||||||
import { ContextInvalidated, createShadowDOM, onContextInvalidated } from 'chrome-extension-toolkit';
|
import { ContextInvalidated, createShadowDOM, onContextInvalidated } from 'chrome-extension-toolkit';
|
||||||
import ContentMain from './ContentMain';
|
import ContentMain from './ContentMain';
|
||||||
import colors from '../styles/colors.module.scss';
|
import colors from '../styles/colors.module.scss';
|
||||||
|
import getPageTypes, { PageType } from './lib/getPageTypes';
|
||||||
|
import { populateSearchInputs } from './lib/courseSchedule/populateSearchInputs';
|
||||||
|
|
||||||
console.log('colors:', colors);
|
const pageTypes = getPageTypes(window.location.href);
|
||||||
|
console.log('pageTypes:', pageTypes);
|
||||||
|
|
||||||
injectReact();
|
if (pageTypes.includes(PageType.COURSE_SCHEDULE)) {
|
||||||
|
if (pageTypes.includes(PageType.COURSE_SCHEDULE_LIST)) {
|
||||||
async function injectReact() {
|
populateSearchInputs();
|
||||||
|
}
|
||||||
const shadowDom = createShadowDOM('ut-registration-plus-dom-container');
|
const shadowDom = createShadowDOM('ut-registration-plus-dom-container');
|
||||||
render(<ContentMain />, shadowDom.shadowRoot);
|
render(<ContentMain />, shadowDom.shadowRoot);
|
||||||
await shadowDom.addStyle('static/css/content.css');
|
shadowDom.addStyle('static/css/content.css');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process.env.NODE_ENV === 'development') {
|
onContextInvalidated(() => {
|
||||||
onContextInvalidated(() => {
|
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
div.id = 'context-invalidated-container';
|
div.id = 'context-invalidated-container';
|
||||||
document.body.appendChild(div);
|
document.body.appendChild(div);
|
||||||
render(<ContextInvalidated color={colors.$CHARCOAL} backgroundColor={colors.$BURNT_ORANGE} />, div);
|
render(
|
||||||
});
|
<ContextInvalidated fontFamily='monospace' color={colors.WHITE} backgroundColor={colors.BURNT_ORANGE} />,
|
||||||
}
|
div
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|||||||
2
src/views/content/lib/courseSchedule/index.ts
Normal file
2
src/views/content/lib/courseSchedule/index.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
|
||||||
20
src/views/content/lib/courseSchedule/populateSearchInputs.ts
Normal file
20
src/views/content/lib/courseSchedule/populateSearchInputs.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* The course schedule page has a search form that allows users to search for courses by department and course level.
|
||||||
|
* The problem is that once the user triggers a search and refreshes the page,
|
||||||
|
* for some reason the search form is cleared and the user has to re-enter their search parameters. This fixes that lol
|
||||||
|
*/
|
||||||
|
export function populateSearchInputs() {
|
||||||
|
let params = new URL(window.location.href).searchParams;
|
||||||
|
let department = params.get('fos_fl');
|
||||||
|
let courseLevel = params.get('level');
|
||||||
|
if (!department || !courseLevel) return;
|
||||||
|
|
||||||
|
const depInput = document.querySelector<HTMLInputElement>('#fos_fl');
|
||||||
|
const levelInput = document.querySelector<HTMLInputElement>('#level');
|
||||||
|
|
||||||
|
if (!depInput || !levelInput) return;
|
||||||
|
|
||||||
|
depInput.value = department;
|
||||||
|
levelInput.value = courseLevel;
|
||||||
|
}
|
||||||
36
src/views/content/lib/getPageTypes.ts
Normal file
36
src/views/content/lib/getPageTypes.ts
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
export enum PageType {
|
||||||
|
EXTENSION_POPUP,
|
||||||
|
COURSE_SCHEDULE,
|
||||||
|
COURSE_SCHEDULE_LIST,
|
||||||
|
COURSE_DETAILS,
|
||||||
|
UT_PLANNER,
|
||||||
|
WAITLIST,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We use this function to determine what page the user is on, and then we can use that information to determine what to do
|
||||||
|
* @param url the url of the current page
|
||||||
|
* @returns a list of page types that the current page is
|
||||||
|
*/
|
||||||
|
export default function getPageTypes(url: string): PageType[] {
|
||||||
|
if (url.includes('chrome-extension://')) {
|
||||||
|
return [PageType.EXTENSION_POPUP];
|
||||||
|
}
|
||||||
|
if (url.includes('utexas.collegescheduler.com')) {
|
||||||
|
return [PageType.UT_PLANNER];
|
||||||
|
}
|
||||||
|
if (url.includes('utdirect.utexas.edu/apps/registrar/course_schedule')) {
|
||||||
|
const types = [PageType.COURSE_SCHEDULE];
|
||||||
|
if (url.includes('results')) {
|
||||||
|
types.push(PageType.COURSE_SCHEDULE_LIST);
|
||||||
|
}
|
||||||
|
if (document.querySelector('#details')) {
|
||||||
|
types.push(PageType.COURSE_DETAILS);
|
||||||
|
}
|
||||||
|
return types;
|
||||||
|
}
|
||||||
|
if (url.includes('utdirect.utexas.edu') && (url.includes('waitlist') || url.includes('classlist'))) {
|
||||||
|
return [PageType.WAITLIST];
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
@@ -11,15 +11,15 @@ $SHADE: #9cadb7;
|
|||||||
$LIMESTONE: #d6d2c4;
|
$LIMESTONE: #d6d2c4;
|
||||||
|
|
||||||
:export {
|
:export {
|
||||||
$BURNT_ORANGE: $BURNT_ORANGE;
|
BURNT_ORANGE: $BURNT_ORANGE;
|
||||||
$CHARCOAL: $CHARCOAL;
|
CHARCOAL: $CHARCOAL;
|
||||||
$WHITE: $WHITE;
|
WHITE: $WHITE;
|
||||||
$TANGERINE: $TANGERINE;
|
TANGERINE: $TANGERINE;
|
||||||
$SUNSHINE: $SUNSHINE;
|
SUNSHINE: $SUNSHINE;
|
||||||
$CACTUS: $CACTUS;
|
CACTUS: $CACTUS;
|
||||||
$TURTLE_POND: $TURTLE_POND;
|
TURTLE_POND: $TURTLE_POND;
|
||||||
$TURQUOISE: $TURQUOISE;
|
TURQUOISE: $TURQUOISE;
|
||||||
$BLUEBONNET: $BLUEBONNET;
|
BLUEBONNET: $BLUEBONNET;
|
||||||
$SHADE: $SHADE;
|
SHADE: $SHADE;
|
||||||
$LIMESTONE: $LIMESTONE;
|
LIMESTONE: $LIMESTONE;
|
||||||
}
|
}
|
||||||
|
|||||||
22
src/views/styles/colors.module.scss.d.ts
vendored
22
src/views/styles/colors.module.scss.d.ts
vendored
@@ -1,15 +1,15 @@
|
|||||||
export interface ISassColors {
|
export interface ISassColors {
|
||||||
$BURNT_ORANGE: string;
|
BURNT_ORANGE: string;
|
||||||
$CHARCOAL: string;
|
CHARCOAL: string;
|
||||||
$WHITE: string;
|
WHITE: string;
|
||||||
$TANGERINE: string;
|
TANGERINE: string;
|
||||||
$SUNSHINE: string;
|
SUNSHINE: string;
|
||||||
$CACTUS: string;
|
CACTUS: string;
|
||||||
$TURTLE_POND: string;
|
TURTLE_POND: string;
|
||||||
$TURQUOISE: string;
|
TURQUOISE: string;
|
||||||
$BLUEBONNET: string;
|
BLUEBONNET: string;
|
||||||
$SHADE: string;
|
SHADE: string;
|
||||||
$LIMESTONE: string;
|
LIMESTONE: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare const colors: ISassColors;
|
declare const colors: ISassColors;
|
||||||
|
|||||||
Reference in New Issue
Block a user