diff --git a/packages/frontend/src/app/configure/page.module.css b/packages/frontend/src/app/configure/page.module.css index 17ef4057..cb8f6499 100644 --- a/packages/frontend/src/app/configure/page.module.css +++ b/packages/frontend/src/app/configure/page.module.css @@ -49,6 +49,78 @@ width: 40%; } +.slidersContainer { + display: flex; + flex-direction: column; + padding: 10px; +} + +.slidersSetting { + display: flex; + flex-direction: column; + width: 100%; +} + +.sliderValue { + margin-right: auto; + padding: 5px; +} + + +.slider { + width: 100%; + margin: 10px 0; + cursor: pointer; + background: #1a1a1a; + outline: none; + -webkit-appearance: none; + appearance: none; + opacity: 0.7; + border-radius: 8px; + height: 15px; + transition: opacity 0.2s; + -webkit-tap-highlight-color: transparent; + +} + +.slider:hover { + opacity: 1; +} + +.sliderMax { + background: linear-gradient(to right, #1b1b1b 0%, #d3d3d3 var(--maxValue), #1a1a1a var(--maxValue), #1a1a1a 100%); +} + +.sliderMin { + background: linear-gradient(to right, #414141 0%, #ffffff var(--minValue), #1a1a1a var(--minValue), #1a1a1a 100%); +} + + +.slider::-webkit-slider-thumb { + -webkit-appearance: none; + appearance: none; + width: 30px; + height: 30px; + background: #dfdfdf; + cursor: pointer; + border-radius: 50%; + transition: transform 0.2s; + -webkit-tap-highlight-color: transparent; +} + +.slider::-moz-range-thumb { + width: 30px; + height: 30px; + background: #dfdfdf; + cursor: pointer; + border-radius: 50%; + transition: transform 0.2s; +} + +.slider::-webkit-slider-thumb:hover { + transform: scale(1.1); +} + .settingInput input[type='checkbox'] { width: 20px; height: 20px; diff --git a/packages/frontend/src/app/configure/page.tsx b/packages/frontend/src/app/configure/page.tsx index 44c259de..44fded01 100644 --- a/packages/frontend/src/app/configure/page.tsx +++ b/packages/frontend/src/app/configure/page.tsx @@ -137,6 +137,13 @@ const defaultServices = [ }, ]; +const formatSize = (size: number | null): string => { + if (size === null) return ''; + return size >= 1000 * 1000 * 1000 + ? `${(size / 1000 / 1000 / 1000).toFixed(2)} GB` + : `${(size / 1000 / 1000).toFixed(2)} MB`; +}; + export default function Configure() { const [resolutions, setResolutions] = useState(defaultResolutions); @@ -303,6 +310,21 @@ export default function Configure() { } }, []); + + useEffect(() => { + const slider = document.querySelector(`.${styles.sliderMin}`) as HTMLElement; + if (slider) { + slider.style.setProperty('--minValue', `${(minSize || 0) / 150000000000 * 100}%`); + } + }, [minSize]); + + useEffect(() => { + const slider = document.querySelector(`.${styles.sliderMax}`) as HTMLElement; + if (slider) { + slider.style.setProperty('--maxValue', `${(maxSize || 0) / 150000000000 * 100}%`); + } + }, [maxSize]); + return (
@@ -408,51 +430,38 @@ export default function Configure() {
-
-
+
+

Size Filter

- Filter streams by size. Leave empty to disable. + Filter streams by size. Leave both sliders at 0 to disable the filter.

-
+
{ - const value = e.target.value - ? parseInt(e.target.value) - : null; - if (value && value <= 0) { - setMinSize(null); - return; - } - setMinSize(value); - }} + type="range" + min="0" + max="150000000000" + step="50000000" + value={minSize || 0} + onChange={(e) => setMinSize(e.target.value === '0' ? null : parseInt(e.target.value))} + className={styles.slider + ' ' + styles.sliderMin} /> +
+ Minimum size: {minSize ? formatSize(minSize) : 'Disabled'} +
{ - const value = e.target.value - ? parseInt(e.target.value) - : null; - if (value && value <= 0) { - setMaxSize(null); - return; - } - setMaxSize(value); - }} + type="range" + min="0" + max="150000000000" + step="50000000" + value={maxSize || 0} + onChange={(e) => setMaxSize(e.target.value === '0' ? null : parseInt(e.target.value))} + className={styles.slider + ' ' + styles.sliderMax} /> - +
+ Maximum size: {maxSize ? formatSize(maxSize) : 'Disabled'} +