mirror of
https://github.com/Viren070/AIOStreams.git
synced 2025-12-01 23:14:04 +01:00
feat(frontend): use 2 sliders instead of number inputs
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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<Resolution[]>(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 (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.content}>
|
||||
@@ -408,51 +430,38 @@ export default function Configure() {
|
||||
</div>
|
||||
|
||||
<div className={styles.section}>
|
||||
<div className={styles.setting}>
|
||||
<div className={styles.settingDescription}>
|
||||
<div className={styles.slidersSetting}>
|
||||
<div>
|
||||
<h2 style={{ padding: '5px' }}>Size Filter</h2>
|
||||
<p style={{ padding: '5px' }}>
|
||||
Filter streams by size. Leave empty to disable.
|
||||
Filter streams by size. Leave both sliders at 0 to disable the filter.
|
||||
</p>
|
||||
</div>
|
||||
<div className={styles.settingInput}>
|
||||
<div className={styles.slidersContainer}>
|
||||
<input
|
||||
type="number"
|
||||
placeholder="Min size"
|
||||
value={minSize || ''}
|
||||
onChange={(e) => {
|
||||
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}
|
||||
/>
|
||||
<div className={styles.sliderValue}>
|
||||
Minimum size: {minSize ? formatSize(minSize) : 'Disabled'}
|
||||
</div>
|
||||
<input
|
||||
type="number"
|
||||
placeholder="Max size"
|
||||
value={maxSize || ''}
|
||||
onChange={(e) => {
|
||||
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}
|
||||
/>
|
||||
<select
|
||||
value={sizeUnit}
|
||||
onChange={(e) => setSizeUnit(e.target.value as 'MB' | 'GB')}
|
||||
>
|
||||
<option value="MB">MB</option>
|
||||
<option value="GB">GB</option>
|
||||
</select>
|
||||
<div className={styles.sliderValue}>
|
||||
Maximum size: {maxSize ? formatSize(maxSize) : 'Disabled'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user