diff --git a/src/app/App.tsx b/src/app/App.tsx index df58c3232..199e209aa 100644 --- a/src/app/App.tsx +++ b/src/app/App.tsx @@ -1,8 +1,6 @@ import React from 'react'; import { MemoryRouter as Router } from 'react-router-dom'; import MainContainer from './containers/MainContainer'; -import { ThemeProvider } from '@mui/material/styles'; -import theme from './styles/theme'; /* 'currentTab' is the current active tab within Google Chrome. @@ -12,12 +10,10 @@ import theme from './styles/theme'; function App(): JSX.Element { return ( - - - {/* we wrap our application with the tag so that all components that are nested will have the react-router context */} - - - + + {/* we wrap our application with the tag so that all components that are nested will have the react-router context */} + + ); } diff --git a/src/app/components/Actions/Action.tsx b/src/app/components/Actions/Action.tsx index 31dd368ae..ee6247aae 100644 --- a/src/app/components/Actions/Action.tsx +++ b/src/app/components/Actions/Action.tsx @@ -1,95 +1,59 @@ -/* eslint-disable react/require-default-props */ -/* eslint-disable @typescript-eslint/no-explicit-any */ -/* eslint-disable react/no-unused-prop-types */ - import React from 'react'; import ReactHover, { Trigger, Hover } from 'react-hover'; import { changeView, changeSlider } from '../../slices/mainSlice'; import { ActionProps, OptionsCursorTrueWithMargin } from '../../FrontendTypes'; import { useDispatch } from 'react-redux'; -/* - This renders the individual snapshot components on the left side column -*/ - -/** - * @function Action - * @param selected : The selected action in the array of state changes - * @param displayName : Label showing sequence number of state change, reflects changes in Chart.tsx - * @param componentName : Displays the name of compenent's state being changed - * @param last : The last index in the array - * @param sliderIndex: Index of the slider in the array of state changes - * (clicking the block changes the slider, related to MainSlider.tsx slider) - * @param componentData: Displays react fiber data - * @param viewIndex: Index of the tab in the array when timejump is made - * @method dispatch Executes actions that changes state in reactime - * @method handleOnkeyDown Executes key commands - * - */ - const Action = (props: ActionProps): JSX.Element => { - //here we are adding useSelector and useDispatch for RTK state conversion const dispatch = useDispatch(); - // We destructure the 'props' that were passed into this component const { - selected, // boolean on whether the current index is the same as the viewIndex in 'ActionContainer' - last, // boolean on (whether the view index is less than 0) AND if (the index is the same as the last snapshot's index value in hierarchyArr) in 'ActionContainer' - index, // from snapshot.index in "ActionContainer's" 'hierarchyArr' - sliderIndex, // from tabs[currentTab] object in 'ActionContainer' - displayName, // from snapshot.displayName in "ActionContainer's" 'hierarchyArr' - componentData, // from snapshot.componentData in "ActionContainer's" 'hierarchyArr' - viewIndex, // from tabs[currentTab] object in 'ActionContainer' + selected, + last, + index, + sliderIndex, + displayName, + componentData, + viewIndex, isCurrIndex, - handleOnkeyDown, // function that allows arrows keys to jump between snapshots defined in 'ActionContainer.tsx' + handleOnkeyDown, } = props; - /** - * @function cleanTime: Displays render times for state changes - * @returns render display time in seconds in milliseconds - */ - const cleanTime = (): string => { if (!componentData || !componentData.actualDuration) { - // if there is no 'componentData' or 'componentData.actualDuration' return 'NO TIME'; } - let seconds: number | string; // seconds is undefined but can take a number or a string - let milliseconds: any = componentData.actualDuration; // milliseconds is of any type and taken from the 'componentData.actualDuration' + let seconds: number | string; + let milliseconds: any = componentData.actualDuration; if (Math.floor(componentData.actualDuration) > 60) { - // if the milliseconds is greater than 60 - seconds = Math.floor(componentData.actualDuration / 60); // we divide our milliseconds by 60 to determine our seconds - seconds = JSON.stringify(seconds); // and we convert our seconds into a string + seconds = Math.floor(componentData.actualDuration / 60); + seconds = JSON.stringify(seconds); if (seconds.length < 2) { - // if the seconds string is only a single digit - seconds = '0'.concat(seconds); // we can add a 0 in front of it so that if 'seconds = "1"' it will come out as 'seconds = "01"' + seconds = '0'.concat(seconds); } - milliseconds = Math.floor(componentData.actualDuration % 60); // Our true milliseconds then becomes the remainder of dividing our initial milliseconds by 60 + milliseconds = Math.floor(componentData.actualDuration % 60); } else { - seconds = '00'; // if we haven't even reached one second yet, our seconds are 00 + seconds = '00'; } - milliseconds = Number.parseFloat(milliseconds as string).toFixed(2); // we convert our milliseconds string into a floating point number that has up to two decimal places. - const arrayMilliseconds: [string, number] = milliseconds.split('.'); // we split our milliseconds using the decimal and come out with an array of two numbers + milliseconds = Number.parseFloat(milliseconds as string).toFixed(2); + const arrayMilliseconds: [string, number] = milliseconds.split('.'); if (arrayMilliseconds[0].length < 2) { - // if our millisecond string only has one digit - arrayMilliseconds[0] = '0'.concat(arrayMilliseconds[0]); // we add a 0 in front of it so that in the a sample number of '1' becomes '01' + arrayMilliseconds[0] = '0'.concat(arrayMilliseconds[0]); } if (index === 0) { - // if this is the initial snapshot - return `${seconds}:${arrayMilliseconds[0]}.${arrayMilliseconds[1]}`; // we give it a timestamp + return `${seconds}:${arrayMilliseconds[0]}.${arrayMilliseconds[1]}`; } - return `+${seconds}:${arrayMilliseconds[0]}.${arrayMilliseconds[1]}`; // if these are succeeding snapshots, we add a '+' to the timestamp + return `+${seconds}:${arrayMilliseconds[0]}.${arrayMilliseconds[1]}`; }; - const displayTime: string = cleanTime(); // we run cleanTime on the creation of this component so that we can get the timestamp + const displayTime: string = cleanTime(); - // creates an options object that 'ReactHover' component will use to modify it's behaviour const optionsCursorTrueWithMargin: OptionsCursorTrueWithMargin = { followCursor: true, shiftX: 20, @@ -123,9 +87,15 @@ const Action = (props: ActionProps): JSX.Element => { placeholder={`Snapshot: ${displayName}`} /> - + {isCurrIndex ? ( + + ) : ( + + )} {isCurrIndex ? (
- {dropdownSelection === 'Provider/Consumer' && } - {dropdownSelection === 'TimeJump' && + {dropdownSelection === 'Provider/Consumer' && } + {dropdownSelection === 'TimeJump' && Object.keys(routes).map((route, i) => ( - )) - } + ))}
) : null} diff --git a/src/app/containers/MainContainer.tsx b/src/app/containers/MainContainer.tsx index 9f91bd980..6d092a88f 100644 --- a/src/app/containers/MainContainer.tsx +++ b/src/app/containers/MainContainer.tsx @@ -33,7 +33,7 @@ function MainContainer(): JSX.Element { const { connectionStatus }: MainState = useSelector((state: RootState) => state.main); // JR 12.22.23: so far this log always returns true - // console.log('MainContainer connectionStatus at initialization: ', connectionStatus); + console.log('MainContainer connectionStatus at initialization: ', connectionStatus); const [actionView, setActionView] = useState(true); // We create a local state 'actionView' and set it to true diff --git a/src/app/styles/abstracts/_variablesLM.scss b/src/app/styles/abstracts/_variablesLM.scss index 75501f4af..a18fc4f7c 100644 --- a/src/app/styles/abstracts/_variablesLM.scss +++ b/src/app/styles/abstracts/_variablesLM.scss @@ -26,17 +26,17 @@ $contrasting-color: #161617; $contrasting-color-weak: #353536; /// HEATMAP COLORS -$heat-level-1: #F1B476; -$heat-level-2: #E4765B; -$heat-level-3: #C64442; -$heat-level-4: #8C2743; +$heat-level-1: #f1b476; +$heat-level-2: #e4765b; +$heat-level-3: #c64442; +$heat-level-4: #8c2743; ///////////////////////////////////////////////////////////////////// // ALL OF THE FOLLOWING COLORS SHOULD REFERENCE A COLOR FROM ABOVE // ///////////////////////////////////////////////////////////////////// /// @type Color - + //general text color theme $dark-text: $contrasting-color; $light-text: $background-color; @@ -70,14 +70,10 @@ $tab-arrow-indicator: lighten($contrasting-color, 30%); //SNAPSHOTS AND ROUTES LIST $action-tab-background: $background-color; $action-cont-border: $contrasting-color; -//$action-clear-button: $primary-color; //currently being handled by mui theme.ts file -//$action-clear-button-text: $background-color; //currently being handled by mui theme.ts file -$route-bar: $primary-color-strong; -$route-bar-text: $light-text; $indiv-action-input-bg: $background-color-strong; $indiv-action-selected: darken($background-color, 15%); $indiv-action-selected-text: $light-text; -$indiv-action-filler-text: lighten($contrasting-color,60%); +$indiv-action-filler-text: lighten($contrasting-color, 60%); $indiv-action-custom-text: $dark-text; $indiv-action-border: $contrasting-color-weak; $indiv-action-time: $primary-color-weak; @@ -98,12 +94,12 @@ $header-button-inactive-text: $dark-text; $header-button-hover: lighten($header-button-inactive, 20%); //the buttons/tabs controlling what is displayed in STATECONTAINER (Map, Performance, History, Web Metrics, Tree) -$navbar-background: $background-color; //this color only shows up in Diff mode when buttons don't fill the whole bar //DIFF FEATURE IS CURRENTLY COMMENTED OUT +$navbar-background: $background-color; //this color only shows up in Diff mode when buttons don't fill the whole bar //DIFF FEATURE IS CURRENTLY COMMENTED OUT $navbar-selected: $primary-color-strong; $navbar-selected-text: $light-text; $navbar-unselected: $primary-color-weak; $navbar-unselected-text: $dark-text; -$navbar-hover: darken($navbar-unselected,15%); +$navbar-hover: darken($navbar-unselected, 15%); $state-background: $background-color-strong; $state-cont-border: $contrasting-color; diff --git a/src/app/styles/components/_actionComponent.scss b/src/app/styles/components/_actionComponent.scss index b28f8fcfc..df28c3ef9 100644 --- a/src/app/styles/components/_actionComponent.scss +++ b/src/app/styles/components/_actionComponent.scss @@ -1,53 +1,129 @@ -.action-component { - padding: 3px 10px; - display: grid; - grid-template-columns: none; - align-items: center; - height: 24px; - // background-color: $brand-color; - // border-bottom-style: solid; - // border-bottom-width: 1px; - // background-color: none; - // border-color: #292929; - // border-color: $border-color; - cursor: pointer; - overflow: hidden; - @extend %disable-highlight; +.route-container { + width: 100%; } -.clear-button { - background-color:#187924; - color:#187924; +.route-header { + background-color: #1f2937; + color: #ffffff; + padding: 10px; + font-size: 14px; } -.action-component-text { - margin-bottom: 8px; - color: $indiv-action-custom-text +.route-content { + display: flex; + flex-direction: row; + margin-bottom: 50px; +} + +/* Container for individual action */ +.individual-action { + margin: 0; + padding: 0; +} + +.action-component { + display: flex; + padding: 6px 16px; + background: white; + border-bottom: 1px solid #e5e7eb; + transition: background-color 200ms ease; +} + +.action-component:hover { + background-color: #f9fafb; } .action-component.selected { - //font-size: 16px; - background-color: $indiv-action-selected; - color: $indiv-action-selected-text + background-color: #f3f4f6; } -.action-component.exclude { - color: #ff0000; +.action-component-trigger { + width: 100%; display: flex; - justify-content: center; - margin-top: 10px; + justify-content: space-between; + align-items: center; +} + +.action-component-text { + flex: 1; } -.action-component:focus { +/* Input styling */ +.actionname { + border: none; + background: transparent; + font-size: 1rem; + color: #374151; + width: 100%; + padding: 2px 0; +} + +.actionname::placeholder { + color: #6b7280; +} + +.actionname:focus { outline: none; } -.action-component-trigger { - display: grid; - grid-template-columns: 4fr 1fr; +/* Button styling */ +.time-button, +.jump-button, +.current-location { + min-width: 90px; + height: 28px; /* Fixed height for better vertical centering */ + padding: 0 8px; /* Reduced vertical padding */ + border-radius: 6px; + font-size: 0.9375rem; + font-weight: 500; + display: flex; align-items: center; - //height: 20px; - cursor: pointer; - overflow: hidden; - @extend %disable-highlight; + justify-content: center; + border: none; + transition: all 200ms ease; + margin: 0; /* Removed top margin */ +} + +.time-button { + color: #6b7280; + background: transparent; +} + +.jump-button { + color: white; + background: #111827; +} + +.jump-button:hover { + background: #374151; +} + +.current-location { + color: #059669; + background: #ecfdf5; +} + +/* Hide/show button transitions */ +.action-component:hover .time-button { + display: none; +} + +.action-component:hover .jump-button { + display: block; +} + +.jump-button { + display: none; +} + +.current-snap { + min-width: 90px; + font-weight: bold; + border: none; + background: transparent; + font-size: 1rem; + color: #374151; + width: 100%; + padding: 2px 0; + text-align: center; } diff --git a/src/app/styles/components/_buttons.scss b/src/app/styles/components/_buttons.scss index 5eb55191e..dd18323de 100644 --- a/src/app/styles/components/_buttons.scss +++ b/src/app/styles/components/_buttons.scss @@ -13,7 +13,9 @@ border-radius: 5px; cursor: pointer; line-height: 1.5em; - font: 400 16px 'Outfit', sans-serif; + font: + 400 16px 'Outfit', + sans-serif; width: 120px; background: $performance-save-series-button; height: 30px; @@ -37,7 +39,9 @@ border-radius: 3px; cursor: pointer; line-height: 1.5em; - font: 300 16px 'Outfit', sans-serif; + font: + 300 16px 'Outfit', + sans-serif; font-size: $button-text-size; width: 120px; height: 30px; @@ -59,17 +63,13 @@ border-radius: 3px; cursor: pointer; line-height: 1.5em; - font: 500 16px 'Roboto', sans-serif; + font: + 500 16px 'Roboto', + sans-serif; width: 120px; //background: #ff0000; } -.clear-button { - background: #3256f1; - background-color: #050787; - color: #3256f1; -} - .empty-button:hover { color: black; box-shadow: #ff0001; @@ -87,7 +87,9 @@ .action-component:hover .jump-button { opacity: 1; transform: rotateX(0deg); - transition: opacity 300ms, transform 0.15s linear; + transition: + opacity 300ms, + transform 0.15s linear; } .time-button { @@ -114,7 +116,9 @@ background-color: #232529; color: #ffffff; transform: rotateX(90deg); - transition: opacity 300ms, transform 0.15s linear; + transition: + opacity 300ms, + transform 0.15s linear; opacity: 0; display: flex; align-items: center; @@ -215,7 +219,9 @@ align-items: center; cursor: pointer; line-height: 1.5em; - font: 300 16px 'Outfit', sans-serif; + font: + 300 16px 'Outfit', + sans-serif; font-size: $button-text-size; background: #ff0001; @@ -234,8 +240,12 @@ background-image: -moz-linear-gradient(top, transparent, rgba(0, 0, 0, 0.4)); background-image: -o-linear-gradient(top, transparent, rgba(0, 0, 0, 0.4)); background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.4)); - -webkit-box-shadow: inset 0 1px rgba(255, 255, 255, 0.1), 0 1px 1px rgba(0, 0, 0, 0.2); - box-shadow: inset 0 1px rgba(255, 255, 255, 0.1), 0 1px 1px rgba(0, 0, 0, 0.2); + -webkit-box-shadow: + inset 0 1px rgba(255, 255, 255, 0.1), + 0 1px 1px rgba(0, 0, 0, 0.2); + box-shadow: + inset 0 1px rgba(255, 255, 255, 0.1), + 0 1px 1px rgba(0, 0, 0, 0.2); } .dropdown-dark:before { @@ -275,7 +285,6 @@ } .dropdown-and-delete-series-container { - display: flex; align-items: center; justify-content: space-around; @@ -462,3 +471,19 @@ aside { margin-left: 5px; margin-right: -22px; } + +.clear-button-modern { + width: 100% !important; + background-color: #f3f4f6 !important; + color: #374151 !important; + font-size: 0.875rem !important; + font-weight: 500 !important; + text-transform: uppercase !important; + padding: 0.375rem 1rem !important; + border-radius: 0.375rem !important; + transition: background-color 200ms ease-in-out !important; +} + +.clear-button-modern:hover { + background-color: #e5e7eb !important; +} diff --git a/src/app/styles/components/_rc-slider.scss b/src/app/styles/components/_rc-slider.scss index e50d273a2..89137886a 100644 --- a/src/app/styles/components/_rc-slider.scss +++ b/src/app/styles/components/_rc-slider.scss @@ -1,250 +1,230 @@ .rc-slider { - position: relative; - width: 100%; - margin: 20px; - border-radius: 6px; - -ms-touch-action: none; - touch-action: none; - box-sizing: border-box; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + position: relative; + width: 100%; + margin: 12px; + border-radius: 6px; + -ms-touch-action: none; + touch-action: none; + box-sizing: border-box; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } .rc-slider * { - box-sizing: border-box; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + box-sizing: border-box; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } .rc-slider-rail { - position: absolute; - width: 100%; - background-color: $slider-rail-right; - height: 4px; - border-radius: 6px; + position: absolute; + width: 100%; + background-color: $slider-rail-right; + height: 4px; + border-radius: 6px; } .rc-slider-track { - position: absolute; - left: 0; - height: 4px; - border-radius: 6px; - background-color: $slider-rail-left; + position: absolute; + left: 0; + height: 4px; + border-radius: 6px; + background-color: $slider-rail-left; } .rc-slider-handle { - position: absolute; - margin-left: -10px; - margin-top: -10px; - width: 25px; - height: 25px; - cursor: pointer; - cursor: -webkit-grab; - cursor: grab; - border-radius: 50%; - background: $slider-handle; - -ms-touch-action: pan-x; - touch-action: pan-x; + position: absolute; + margin-left: -8px; + width: 20px; + height: 20px; + cursor: pointer; + cursor: -webkit-grab; + cursor: grab; + border-radius: 50%; + background: #374151; + border: none; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + transition: + transform 0.2s ease, + box-shadow 0.2s ease; + -ms-touch-action: pan-x; + touch-action: pan-x; } .rc-slider-handle:focus { - border-color: #ff0001; - outline: none; -} -.rc-slider-handle-click-focused:focus { - border-color: #ff0001; + outline: none; } + .rc-slider-handle:hover { - border-color: #ff0001; + transform: scale(1.1); + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.15); } .rc-slider-handle:active { - //background: #f00004; - border-color: #ff0001; - cursor: -webkit-grabbing; - cursor: grabbing; + cursor: -webkit-grabbing; + cursor: grabbing; + transform: scale(1.1); + box-shadow: 0 3px 8px rgba(0, 0, 0, 0.2); } .rc-slider-mark { - position: absolute; - top: 18px; - left: 0; - width: 100%; - font-size: 16px; + position: absolute; + top: 18px; + left: 0; + width: 100%; + font-size: 16px; } .rc-slider-mark-text { - position: absolute; - display: inline-block; - vertical-align: middle; - text-align: center; - cursor: pointer; - color: #999; + position: absolute; + display: inline-block; + vertical-align: middle; + text-align: center; + cursor: pointer; + color: #999; } .rc-slider-mark-text-active { - color: #666; + color: #666; } .rc-slider-step { - position: absolute; - width: 100%; - height: 4px; - background: transparent; -} -.rc-slider-dot { - position: absolute; - bottom: -2px; - margin-left: -4px; - width: 8px; - height: 8px; - border: 2px solid #ff0001; - background-color: #fff; - cursor: pointer; - border-radius: 50%; - vertical-align: middle; -} -.rc-slider-dot-active { - border-color: #96dbfa; -} -.rc-slider-disabled { - background-color: #ff0001; + position: absolute; + width: 100%; + height: 4px; + background: transparent; } + .rc-slider-disabled .rc-slider-track { - background-color: #ccc; + background-color: #ccc; } .rc-slider-disabled .rc-slider-handle, .rc-slider-disabled .rc-slider-dot { - border-color: #ccc; - box-shadow: none; - background-color: #fff; - cursor: not-allowed; + border-color: #ccc; + box-shadow: none; + background-color: #fff; + cursor: not-allowed; } .rc-slider-disabled .rc-slider-mark-text, .rc-slider-disabled .rc-slider-dot { - cursor: not-allowed !important; + cursor: not-allowed !important; } .rc-slider-vertical { - width: 14px; - height: 100%; - padding: 0 5px; + width: 14px; + height: 100%; + padding: 0 5px; } .rc-slider-vertical .rc-slider-rail { - height: 100%; - width: 4px; + height: 100%; + width: 4px; } .rc-slider-vertical .rc-slider-track { - left: 5px; - bottom: 0; - width: 4px; + left: 5px; + bottom: 0; + width: 4px; } .rc-slider-vertical .rc-slider-handle { - margin-left: -5px; - margin-bottom: -7px; - -ms-touch-action: pan-y; - touch-action: pan-y; + -ms-touch-action: pan-y; + touch-action: pan-y; } .rc-slider-vertical .rc-slider-mark { - top: 0; - left: 18px; - height: 100%; + top: 0; + left: 18px; + height: 100%; } .rc-slider-vertical .rc-slider-step { - height: 100%; - width: 4px; -} -.rc-slider-vertical .rc-slider-dot { - left: 2px; - margin-bottom: -4px; + height: 100%; + width: 4px; } + .rc-slider-vertical .rc-slider-dot:first-child { - margin-bottom: -4px; + margin-bottom: -4px; } .rc-slider-vertical .rc-slider-dot:last-child { - margin-bottom: -4px; + margin-bottom: -4px; } .rc-slider-tooltip-zoom-down-enter, .rc-slider-tooltip-zoom-down-appear { - animation-duration: 0.3s; - animation-fill-mode: both; - display: block !important; - animation-play-state: paused; + animation-duration: 0.3s; + animation-fill-mode: both; + display: block !important; + animation-play-state: paused; } .rc-slider-tooltip-zoom-down-leave { - animation-duration: 0.3s; - animation-fill-mode: both; - display: block !important; - animation-play-state: paused; + animation-duration: 0.3s; + animation-fill-mode: both; + display: block !important; + animation-play-state: paused; } .rc-slider-tooltip-zoom-down-enter.rc-slider-tooltip-zoom-down-enter-active, .rc-slider-tooltip-zoom-down-appear.rc-slider-tooltip-zoom-down-appear-active { - animation-name: rcSliderTooltipZoomDownIn; - animation-play-state: running; + animation-name: rcSliderTooltipZoomDownIn; + animation-play-state: running; } .rc-slider-tooltip-zoom-down-leave.rc-slider-tooltip-zoom-down-leave-active { - animation-name: rcSliderTooltipZoomDownOut; - animation-play-state: running; + animation-name: rcSliderTooltipZoomDownOut; + animation-play-state: running; } .rc-slider-tooltip-zoom-down-enter, .rc-slider-tooltip-zoom-down-appear { - transform: scale(0, 0); - animation-timing-function: cubic-bezier(0.23, 1, 0.32, 1); + transform: scale(0, 0); + animation-timing-function: cubic-bezier(0.23, 1, 0.32, 1); } .rc-slider-tooltip-zoom-down-leave { - animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); + animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); } @keyframes rcSliderTooltipZoomDownIn { - 0% { - opacity: 0; - transform-origin: 50% 100%; - transform: scale(0, 0); - } - 100% { - transform-origin: 50% 100%; - transform: scale(1, 1); - } + 0% { + opacity: 0; + transform-origin: 50% 100%; + transform: scale(0, 0); + } + 100% { + transform-origin: 50% 100%; + transform: scale(1, 1); + } } @keyframes rcSliderTooltipZoomDownOut { - 0% { - transform-origin: 50% 100%; - transform: scale(1, 1); - } - 100% { - opacity: 0; - transform-origin: 50% 100%; - transform: scale(0, 0); - } + 0% { + transform-origin: 50% 100%; + transform: scale(1, 1); + } + 100% { + opacity: 0; + transform-origin: 50% 100%; + transform: scale(0, 0); + } } .rc-slider-tooltip { - position: absolute; - left: -9999px; - top: -9999px; - visibility: visible; - box-sizing: border-box; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + position: absolute; + left: -9999px; + top: -9999px; + visibility: visible; + box-sizing: border-box; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } .rc-slider-tooltip * { - box-sizing: border-box; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + box-sizing: border-box; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } .rc-slider-tooltip-hidden { - display: none; + display: none; } .rc-slider-tooltip-placement-top { - padding: 4px 0 8px 0; + padding: 4px 0 8px 0; } .rc-slider-tooltip-inner { - padding: 6px 2px; - min-width: 24px; - height: 24px; - font-size: 16px; - line-height: 1; - color: #fff; - text-align: center; - text-decoration: none; - background-color: #6c6c6c; - border-radius: 6px; + padding: 6px 2px; + min-width: 24px; + height: 24px; + font-size: 16px; + line-height: 1; + color: #fff; + text-align: center; + text-decoration: none; + background-color: #6c6c6c; + border-radius: 6px; } .rc-slider-tooltip-arrow { - position: absolute; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; } .rc-slider-tooltip-placement-top .rc-slider-tooltip-arrow { - bottom: 4px; - left: 50%; - margin-left: -4px; - border-width: 4px 4px 0; - border-top-color: #6c6c6c; + bottom: 4px; + left: 50%; + margin-left: -4px; + border-width: 4px 4px 0; + border-top-color: #6c6c6c; } diff --git a/src/app/styles/layout/_actionContainer.scss b/src/app/styles/layout/_actionContainer.scss index 57a5655fe..c3d385926 100644 --- a/src/app/styles/layout/_actionContainer.scss +++ b/src/app/styles/layout/_actionContainer.scss @@ -1,7 +1,8 @@ .action-container { - // overflow: auto; + background: white; + border-right: 1px solid #e5e7eb; + transition: width 0.3s ease; overflow-x: hidden; - background-color: $action-tab-background; } .actionname { @@ -22,11 +23,13 @@ } .actionToolContainer { - color: #873b3b; + color: #374151; display: flex; justify-content: space-between; align-items: center; - height: 35px; + height: 44px; + border-bottom: 1px solid #e5e7eb; + padding: 0 8px; } #recordBtn .fa-regular { @@ -34,14 +37,10 @@ width: 28px; } -.route { - background-color: $route-bar; - color: $route-bar-text; - padding-left: 10px; - padding-top: 5px; - padding-bottom: 5px; -} - .toggle-record { color: $toggle-record-text; -} \ No newline at end of file +} + +.clear-button-container { + padding: 16px; +} diff --git a/src/app/styles/theme.ts b/src/app/styles/theme.ts deleted file mode 100644 index d3e93e2bc..000000000 --- a/src/app/styles/theme.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { createTheme } from '@mui/material/styles'; -const theme = createTheme({ - // typography: { - // fontSize: 2, - // }, - palette: { - primary: { - main: '#3c6e71', - }, - secondary: { - main: '#3c6e71', - }, - }, - components: { - // Name of the component - - MuiButton: { - styleOverrides: { - // Name of the slot - root: { - // Some CSS - fontSize: '0.8rem', - letterSpacing: '0.1rem', - lineHeight: '0.8rem', - }, - }, - }, - }, -}); - -export default theme; diff --git a/src/backend/types/backendTypes.ts b/src/backend/types/backendTypes.ts index ea18224ac..863a4d38d 100644 --- a/src/backend/types/backendTypes.ts +++ b/src/backend/types/backendTypes.ts @@ -252,23 +252,3 @@ export type Fiber = { export type FiberRoot = { current: Fiber; }; - -export interface Window { - __REACTIME_TIME_TRAVEL__: { - getReducerState: (reducerId: symbol) => any; - travelToState: (reducerId: symbol, targetState: any) => void; - }; - __REACTIME_REDUCER_MAP__: Map< - symbol, - { - actionHistory: any[]; - dispatch: (action: any) => void; - initialState: any; - currentState: any; - reducer: (state: any, action: any) => any; - } - >; - __REACTIME_DEBUG__?: { - checkOverride: () => void; - }; -} diff --git a/src/extension/build/manifest.json b/src/extension/build/manifest.json index eea78aab5..e7bc7398c 100644 --- a/src/extension/build/manifest.json +++ b/src/extension/build/manifest.json @@ -13,13 +13,6 @@ "128": "assets/whiteBlackSquareIcon128.png" }, "content_scripts": [ - { - "matches": [""], - "js": ["bundles/overrideReducer.bundle.js"], - "run_at": "document_start", - "all_frames": true, - "world": "MAIN" - }, { "matches": ["http://localhost/*"], "js": ["bundles/content.bundle.js"] @@ -27,7 +20,7 @@ ], "web_accessible_resources": [ { - "resources": ["bundles/backend.bundle.js", "bundles/overrideReducer.bundle.js"], + "resources": ["bundles/backend.bundle.js"], "matches": [""] } ], diff --git a/src/extension/build/panel.html b/src/extension/build/panel.html index b97ee64aa..af4832dc8 100644 --- a/src/extension/build/panel.html +++ b/src/extension/build/panel.html @@ -1,10 +1,10 @@ - + - Reactime 23.0 + Reactime 26.0 diff --git a/src/extension/overrideReducer.js b/src/extension/overrideReducer.js deleted file mode 100644 index 5b3005264..000000000 --- a/src/extension/overrideReducer.js +++ /dev/null @@ -1,257 +0,0 @@ -// (function () { -// console.log('[Reactime Debug] Initial override script loaded'); - -// let attempts = 0; -// const MAX_ATTEMPTS = 50; - -// function verifyReactHooks() { -// return ( -// window.React && -// typeof window.React.useReducer === 'function' && -// typeof window.React.useState === 'function' -// ); -// } - -// const checkReact = () => { -// attempts++; -// console.log(`[Reactime Debug] Checking for React (attempt ${attempts})`); - -// // Only proceed if we can verify React hooks exist -// if (verifyReactHooks()) { -// console.log('[Reactime Debug] Found React with hooks via window.React'); -// setupOverride(); -// return; -// } - -// // Look for React devtools hook -// if (window.__REACT_DEVTOOLS_GLOBAL_HOOK__) { -// console.log('[Reactime Debug] Found React DevTools hook'); - -// // Watch for React registration -// const originalInject = window.__REACT_DEVTOOLS_GLOBAL_HOOK__.inject; -// console.log('[Reactime Debug] Original inject method:', originalInject); //ellie - -// window.__REACT_DEVTOOLS_GLOBAL_HOOK__.inject = function (reactInstance) { -// console.log( -// '[Reactime Debug] React registered with DevTools, verifying hooks availability', -// ); - -// // Give React a moment to fully initialize -// setTimeout(() => { -// if (verifyReactHooks()) { -// console.log('[Reactime Debug] Hooks verified after DevTools registration'); -// setupOverride(); -// } else { -// console.log( -// '[Reactime Debug] Hooks not available after DevTools registration, continuing to check', -// ); -// waitForHooks(); -// } -// }, 2000); - -// return originalInject.apply(this, arguments); -// }; - -// return; -// } - -// waitForHooks(); -// }; - -// function waitForHooks() { -// if (attempts < MAX_ATTEMPTS) { -// const delay = Math.min(100 * attempts, 2000); -// console.log(`[Reactime Debug] Hooks not found, retrying in ${delay}ms`); -// setTimeout(checkReact, delay); -// } else { -// console.log('[Reactime Debug] Max attempts reached, React hooks not found'); -// } -// } - -// function setupOverride() { -// try { -// console.log('[Reactime Debug] Setting up useReducer override'); - -// if (!verifyReactHooks()) { -// throw new Error('React hooks not available during override setup'); -// } - -// const originalUseReducer = window.React.useReducer; -// window.__REACTIME_REDUCER_MAP__ = new Map(); - -// window.React.useReducer = function (reducer, initialArg, init) { -// console.log('[Reactime Debug] useReducer called with:', { -// reducerName: reducer?.name || 'anonymous', -// hasInitialArg: initialArg !== undefined, -// hasInit: !!init, -// }); - -// const actualInitialState = init ? init(initialArg) : initialArg; - -// const wrappedReducer = (state, action) => { -// try { -// console.log('[Reactime Debug] Reducer called:', { -// actionType: action?.type, -// isTimeTravel: action?.type === '__REACTIME_TIME_TRAVEL__', -// currentState: state, -// action, -// }); - -// if (action && action.type === '__REACTIME_TIME_TRAVEL__') { -// return action.payload; -// } -// return reducer(state, action); -// } catch (error) { -// console.error('[Reactime Debug] Error in wrapped reducer:', error); -// return state; -// } -// }; - -// const [state, dispatch] = originalUseReducer(wrappedReducer, actualInitialState); -// const reducerId = Symbol('reactimeReducer'); - -// console.log('[Reactime Debug] New reducer instance created:', { -// reducerId: reducerId.toString(), -// initialState: actualInitialState, -// currentState: state, -// }); - -// window.__REACTIME_REDUCER_MAP__.set(reducerId, { -// actionHistory: [], -// dispatch, -// initialState: actualInitialState, -// currentState: state, -// reducer: wrappedReducer, -// }); - -// const wrappedDispatch = (action) => { -// try { -// console.log('[Reactime Debug] Dispatch called:', { -// reducerId: reducerId.toString(), -// action, -// currentMapSize: window.__REACTIME_REDUCER_MAP__.size, -// }); - -// const reducerInfo = window.__REACTIME_REDUCER_MAP__.get(reducerId); -// reducerInfo.actionHistory.push(action); -// reducerInfo.currentState = wrappedReducer(reducerInfo.currentState, action); -// dispatch(action); -// } catch (error) { -// console.error('[Reactime Debug] Error in wrapped dispatch:', error); -// dispatch(action); -// } -// }; - -// return [state, wrappedDispatch]; -// }; - -// console.log('[Reactime Debug] useReducer successfully overridden'); -// } catch (error) { -// console.error('[Reactime Debug] Error during override setup:', error); -// // If override fails, try again after a delay -// setTimeout(checkReact, 500); -// } -// } - -// // Start checking for React -// checkReact(); - -// // Watch for dynamic React loading -// const observer = new MutationObserver((mutations) => { -// if (verifyReactHooks()) { -// console.log('[Reactime Debug] React hooks found after DOM mutation'); -// observer.disconnect(); -// setupOverride(); -// } -// }); - -// observer.observe(document, { -// childList: true, -// subtree: true, -// }); -// })(); - - -(function () { - console.log('[Reactime Debug] Initial override script loaded'); - - // Retry constants - const MAX_ATTEMPTS = 50; - let attempts = 0; - - // Verify React hooks via registered renderers - function verifyReactHooks() { - try { - const renderers = Array.from( - window.__REACT_DEVTOOLS_GLOBAL_HOOK__.renderers.values() - ); - return renderers.some((renderer) => renderer?.currentDispatcher?.useReducer); - } catch (err) { - console.error('[Reactime Debug] Error verifying React hooks:', err); - return false; - } - } - - // Set up the useReducer override - function setupOverride() { - console.log('[Reactime Debug] Setting up useReducer override'); - - try { - const renderers = Array.from( - window.__REACT_DEVTOOLS_GLOBAL_HOOK__.renderers.values() - ); - const renderer = renderers[0]; // Assume first renderer for simplicity - const originalUseReducer = renderer?.currentDispatcher?.useReducer; - - if (!originalUseReducer) { - throw new Error('useReducer not found in React renderer.'); - } - - renderer.currentDispatcher.useReducer = function (reducer, initialArg, init) { - console.log('[Reactime Debug] useReducer intercepted:', reducer.name || 'anonymous'); - - const wrappedReducer = (state, action) => { - console.log('[Reactime Debug] Reducer called:', { state, action }); - return reducer(state, action); - }; - - return originalUseReducer(wrappedReducer, initialArg, init); - }; - - console.log('[Reactime Debug] useReducer successfully overridden.'); - } catch (err) { - console.error('[Reactime Debug] Error in setupOverride:', err); - } - } - - // Attempt to detect React and set up override - function checkReact() { - attempts++; - console.log(`[Reactime Debug] Checking for React (attempt ${attempts}/${MAX_ATTEMPTS})`); - - if (verifyReactHooks()) { - console.log('[Reactime Debug] React hooks found. Setting up overrides.'); - setupOverride(); - } else if (attempts < MAX_ATTEMPTS) { - setTimeout(checkReact, Math.min(100 * attempts, 2000)); - } else { - console.log('[Reactime Debug] Max attempts reached. React hooks not found.'); - } - } - - // Hook into the inject method of React DevTools - if (window.__REACT_DEVTOOLS_GLOBAL_HOOK__) { - const originalInject = window.__REACT_DEVTOOLS_GLOBAL_HOOK__.inject; - - window.__REACT_DEVTOOLS_GLOBAL_HOOK__.inject = function (renderer) { - console.log('[Reactime Debug] React renderer registered.'); - setupOverride(); // React is registered, so immediately set up overrides - return originalInject.apply(this, arguments); - }; - - console.log('[Reactime Debug] React DevTools hook overridden.'); - } else { - console.log('[Reactime Debug] React DevTools hook not found. Starting manual checks.'); - checkReact(); // Start retries if no DevTools hook - } -})(); diff --git a/webpack.config.js b/webpack.config.js index b455c200f..b64c21032 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -17,7 +17,6 @@ module.exports = { background: './src/extension/background.js', content: './src/extension/contentScript.ts', backend: './src/backend/index.ts', - overrideReducer: './src/extension/overrideReducer.js', }, watchOptions: { aggregateTimeout: 1000,