Refactor input range
This commit is contained in:
parent
d434df8a3b
commit
22efc8e833
140
src/components/rangeSelector.ts
Normal file
140
src/components/rangeSelector.ts
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
import { isTouchSupported } from "../helpers/touchSupport";
|
||||||
|
import { clamp } from "../helpers/number";
|
||||||
|
|
||||||
|
type SUPEREVENT = MouseEvent | TouchEvent;
|
||||||
|
|
||||||
|
export default class RangeSelector {
|
||||||
|
public container: HTMLDivElement;
|
||||||
|
protected filled: HTMLDivElement;
|
||||||
|
protected seek: HTMLInputElement;
|
||||||
|
|
||||||
|
public mousedown = false;
|
||||||
|
|
||||||
|
private events: Partial<{
|
||||||
|
//onMouseMove: ProgressLine['onMouseMove'],
|
||||||
|
onMouseDown: RangeSelector['onMouseDown'],
|
||||||
|
onMouseUp: RangeSelector['onMouseUp'],
|
||||||
|
onScrub: (scrubTime: number) => void
|
||||||
|
}> = {};
|
||||||
|
|
||||||
|
protected decimals: number;
|
||||||
|
|
||||||
|
constructor(protected step: number, protected value: number, protected min: number, protected max: number) {
|
||||||
|
this.container = document.createElement('div');
|
||||||
|
this.container.classList.add('progress-line');
|
||||||
|
|
||||||
|
this.filled = document.createElement('div');
|
||||||
|
this.filled.classList.add('progress-line__filled');
|
||||||
|
|
||||||
|
const seek = this.seek = document.createElement('input');
|
||||||
|
seek.classList.add('progress-line__seek');
|
||||||
|
//seek.setAttribute('max', '0');
|
||||||
|
seek.type = 'range';
|
||||||
|
seek.step = '' + step;
|
||||||
|
seek.min = '' + this.min;
|
||||||
|
seek.max = '' + this.max;
|
||||||
|
seek.value = '' + value;
|
||||||
|
|
||||||
|
/* this.seek.addEventListener('change', (e) => {
|
||||||
|
console.log('seek change', e);
|
||||||
|
}); */
|
||||||
|
|
||||||
|
if(value) {
|
||||||
|
this.setProgress(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
const stepStr = '' + this.step;
|
||||||
|
const index = stepStr.indexOf('.');
|
||||||
|
this.decimals = index === -1 ? 0 : stepStr.length - index - 1;
|
||||||
|
|
||||||
|
//this.setListeners();
|
||||||
|
|
||||||
|
this.container.append(this.filled, seek);
|
||||||
|
}
|
||||||
|
|
||||||
|
public setHandlers(events: RangeSelector['events']) {
|
||||||
|
this.events = events;
|
||||||
|
}
|
||||||
|
|
||||||
|
onMouseMove = (e: SUPEREVENT) => {
|
||||||
|
this.mousedown && this.scrub(e);
|
||||||
|
};
|
||||||
|
|
||||||
|
onMouseDown = (e: SUPEREVENT) => {
|
||||||
|
this.scrub(e);
|
||||||
|
this.mousedown = true;
|
||||||
|
this.events?.onMouseDown && this.events.onMouseDown(e);
|
||||||
|
};
|
||||||
|
|
||||||
|
onMouseUp = (e: SUPEREVENT) => {
|
||||||
|
this.mousedown = false;
|
||||||
|
this.events?.onMouseUp && this.events.onMouseUp(e);
|
||||||
|
};
|
||||||
|
|
||||||
|
public setListeners() {
|
||||||
|
this.container.addEventListener('mousemove', this.onMouseMove);
|
||||||
|
this.container.addEventListener('mousedown', this.onMouseDown);
|
||||||
|
this.container.addEventListener('mouseup', this.onMouseUp);
|
||||||
|
|
||||||
|
if(isTouchSupported) {
|
||||||
|
this.container.addEventListener('touchmove', this.onMouseMove, {passive: true});
|
||||||
|
this.container.addEventListener('touchstart', this.onMouseDown, {passive: true});
|
||||||
|
this.container.addEventListener('touchend', this.onMouseUp, {passive: true});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public setProgress(value: number) {
|
||||||
|
this.setFilled(value);
|
||||||
|
this.seek.value = '' + value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setFilled(value: number) {
|
||||||
|
let percents = (value - this.min) / (this.max - this.min);
|
||||||
|
percents = clamp(percents, 0, 1);
|
||||||
|
//console.log('setFilled', percents, value);
|
||||||
|
this.filled.style.width = (percents * 100) + '%';
|
||||||
|
//this.filled.style.transform = 'scaleX(' + scaleX + ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected scrub(e: SUPEREVENT) {
|
||||||
|
let offsetX: number;
|
||||||
|
const rect = (e.target as HTMLElement).getBoundingClientRect();
|
||||||
|
if(e instanceof MouseEvent) {
|
||||||
|
offsetX = e.pageX - Math.round(rect.left);
|
||||||
|
} else { // touch
|
||||||
|
offsetX = e.targetTouches[0].pageX - Math.round(rect.left);
|
||||||
|
}
|
||||||
|
|
||||||
|
let value = this.min + (offsetX / Math.round(rect.width) * (this.max - this.min));
|
||||||
|
|
||||||
|
if((value - this.min) < ((this.max - this.min) / 2)) {
|
||||||
|
value -= this.step / 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
//console.log('scrub value:', value, this.decimals, offsetX, rect.width, e);
|
||||||
|
value = +value.toFixed(this.decimals);
|
||||||
|
//const dotIndex = ('' + value).indexOf('.');
|
||||||
|
//value = +('' + value).slice(0, this.decimals ? dotIndex + this.decimals : dotIndex);
|
||||||
|
|
||||||
|
value = clamp(value, this.min, this.max);
|
||||||
|
|
||||||
|
this.setFilled(value);
|
||||||
|
|
||||||
|
this.events?.onScrub && this.events.onScrub(value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public removeListeners() {
|
||||||
|
this.container.removeEventListener('mousemove', this.onMouseMove);
|
||||||
|
this.container.removeEventListener('mousedown', this.onMouseDown);
|
||||||
|
this.container.removeEventListener('mouseup', this.onMouseUp);
|
||||||
|
|
||||||
|
if(isTouchSupported) {
|
||||||
|
this.container.removeEventListener('touchmove', this.onMouseMove);
|
||||||
|
this.container.removeEventListener('touchstart', this.onMouseDown);
|
||||||
|
this.container.removeEventListener('touchend', this.onMouseUp);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.events = {};
|
||||||
|
}
|
||||||
|
}
|
@ -28,6 +28,7 @@ import appMessagesManager from "../../lib/appManagers/appMessagesManager";
|
|||||||
import apiManagerProxy from "../../lib/mtproto/mtprotoworker";
|
import apiManagerProxy from "../../lib/mtproto/mtprotoworker";
|
||||||
import AppSearchSuper from "../appSearchSuper.";
|
import AppSearchSuper from "../appSearchSuper.";
|
||||||
import { DateData, fillTipDates } from "../../helpers/date";
|
import { DateData, fillTipDates } from "../../helpers/date";
|
||||||
|
import AppGeneralSettingsTab from "./tabs/generalSettings";
|
||||||
|
|
||||||
const addMembersTab = new AppAddMembersTab();
|
const addMembersTab = new AppAddMembersTab();
|
||||||
const contactsTab = new AppContactsTab();
|
const contactsTab = new AppContactsTab();
|
||||||
@ -73,6 +74,7 @@ export class AppSidebarLeft extends SidebarSlider {
|
|||||||
public chatFoldersTab: AppChatFoldersTab;
|
public chatFoldersTab: AppChatFoldersTab;
|
||||||
public editFolderTab: AppEditFolderTab;
|
public editFolderTab: AppEditFolderTab;
|
||||||
public includedChatsTab: AppIncludedChatsTab;
|
public includedChatsTab: AppIncludedChatsTab;
|
||||||
|
public generalSettingsTab: AppGeneralSettingsTab;
|
||||||
|
|
||||||
//private log = logger('SL');
|
//private log = logger('SL');
|
||||||
|
|
||||||
@ -107,6 +109,7 @@ export class AppSidebarLeft extends SidebarSlider {
|
|||||||
this.editFolderTab = new AppEditFolderTab(this);
|
this.editFolderTab = new AppEditFolderTab(this);
|
||||||
this.includedChatsTab = new AppIncludedChatsTab(this);
|
this.includedChatsTab = new AppIncludedChatsTab(this);
|
||||||
this.editProfileTab = new AppEditProfileTab(this);
|
this.editProfileTab = new AppEditProfileTab(this);
|
||||||
|
this.generalSettingsTab = new AppGeneralSettingsTab(this);
|
||||||
|
|
||||||
this.menuEl = this.toolsBtn.querySelector('.btn-menu');
|
this.menuEl = this.toolsBtn.querySelector('.btn-menu');
|
||||||
this.newBtnMenu = this.sidebarEl.querySelector('#new-menu');
|
this.newBtnMenu = this.sidebarEl.querySelector('#new-menu');
|
||||||
|
90
src/components/sidebarLeft/tabs/generalSettings.ts
Normal file
90
src/components/sidebarLeft/tabs/generalSettings.ts
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
import { SliderSuperTab } from "../../slider"
|
||||||
|
import { AppSidebarLeft } from "..";
|
||||||
|
import RangeSelector from "../../rangeSelector";
|
||||||
|
import { clamp } from "../../../helpers/number";
|
||||||
|
|
||||||
|
export class RangeSettingSelector {
|
||||||
|
public container: HTMLDivElement;
|
||||||
|
private range: RangeSelector;
|
||||||
|
|
||||||
|
constructor(name: string, step: number, initialValue: number, minValue: number, maxValue: number) {
|
||||||
|
const BASE_CLASS = 'range-setting-selector';
|
||||||
|
this.container = document.createElement('div');
|
||||||
|
this.container.classList.add(BASE_CLASS);
|
||||||
|
|
||||||
|
const details = document.createElement('div');
|
||||||
|
details.classList.add(BASE_CLASS + '-details');
|
||||||
|
|
||||||
|
const nameDiv = document.createElement('div');
|
||||||
|
nameDiv.classList.add(BASE_CLASS + '-name');
|
||||||
|
nameDiv.innerHTML = name;
|
||||||
|
|
||||||
|
const valueDiv = document.createElement('div');
|
||||||
|
valueDiv.classList.add(BASE_CLASS + '-value');
|
||||||
|
valueDiv.innerHTML = '' + initialValue;
|
||||||
|
|
||||||
|
details.append(nameDiv, valueDiv);
|
||||||
|
|
||||||
|
this.range = new RangeSelector(step, initialValue, minValue, maxValue);
|
||||||
|
this.range.setListeners();
|
||||||
|
this.range.setHandlers({
|
||||||
|
onScrub: value => {
|
||||||
|
//console.log('font size scrub:', value);
|
||||||
|
valueDiv.innerText = '' + value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.container.append(details, this.range.container);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class AppGeneralSettingsTab extends SliderSuperTab {
|
||||||
|
constructor(appSidebarLeft: AppSidebarLeft) {
|
||||||
|
super(appSidebarLeft);
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.container.classList.add('general-settings-container');
|
||||||
|
this.title.innerText = 'General';
|
||||||
|
|
||||||
|
const generateSection = (name: string) => {
|
||||||
|
const container = document.createElement('div');
|
||||||
|
container.classList.add('sidebar-left-section');
|
||||||
|
|
||||||
|
const hr = document.createElement('hr');
|
||||||
|
const h2 = document.createElement('div');
|
||||||
|
h2.classList.add('sidebar-left-section-name');
|
||||||
|
h2.innerHTML = name;
|
||||||
|
|
||||||
|
const content = document.createElement('div');
|
||||||
|
content.classList.add('sidebar-left-section-content');
|
||||||
|
content.append(h2);
|
||||||
|
|
||||||
|
container.append(hr, content);
|
||||||
|
|
||||||
|
this.scrollable.append(container);
|
||||||
|
|
||||||
|
return content;
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
const container = generateSection('Settings');
|
||||||
|
|
||||||
|
const range = new RangeSettingSelector('Message Text Size', 1, 16, 12, 20);
|
||||||
|
|
||||||
|
container.append(range.container);
|
||||||
|
}
|
||||||
|
|
||||||
|
generateSection('Keyboard');
|
||||||
|
generateSection('Auto-Download Media');
|
||||||
|
generateSection('Auto-Play Media');
|
||||||
|
generateSection('Stickers');
|
||||||
|
}
|
||||||
|
|
||||||
|
onOpen() {
|
||||||
|
if(this.init) {
|
||||||
|
this.init();
|
||||||
|
this.init = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -54,7 +54,7 @@ export default class AppSettingsTab extends SliderSuperTab {
|
|||||||
const className = 'profile-button btn-primary btn-transparent';
|
const className = 'profile-button btn-primary btn-transparent';
|
||||||
buttonsDiv.append(this.buttons.edit = Button(className, {icon: 'edit', rippleSquare: true, text: 'Edit Profile'}));
|
buttonsDiv.append(this.buttons.edit = Button(className, {icon: 'edit', rippleSquare: true, text: 'Edit Profile'}));
|
||||||
buttonsDiv.append(this.buttons.folders = Button(className, {icon: 'folder', rippleSquare: true, text: 'Chat Folders'}));
|
buttonsDiv.append(this.buttons.folders = Button(className, {icon: 'folder', rippleSquare: true, text: 'Chat Folders'}));
|
||||||
buttonsDiv.append(this.buttons.general = Button(className + ' btn-disabled', {icon: 'settings', rippleSquare: true, text: 'General Settings'}));
|
buttonsDiv.append(this.buttons.general = Button(className, {icon: 'settings', rippleSquare: true, text: 'General Settings'}));
|
||||||
buttonsDiv.append(this.buttons.notifications = Button(className + ' btn-disabled', {icon: 'unmute', rippleSquare: true, text: 'Notifications'}));
|
buttonsDiv.append(this.buttons.notifications = Button(className + ' btn-disabled', {icon: 'unmute', rippleSquare: true, text: 'Notifications'}));
|
||||||
buttonsDiv.append(this.buttons.privacy = Button(className + ' btn-disabled', {icon: 'lock', rippleSquare: true, text: 'Privacy and Security'}));
|
buttonsDiv.append(this.buttons.privacy = Button(className + ' btn-disabled', {icon: 'lock', rippleSquare: true, text: 'Privacy and Security'}));
|
||||||
buttonsDiv.append(this.buttons.language = Button(className + ' btn-disabled', {icon: 'language', rippleSquare: true, text: 'Language'}));
|
buttonsDiv.append(this.buttons.language = Button(className + ' btn-disabled', {icon: 'language', rippleSquare: true, text: 'Language'}));
|
||||||
@ -74,6 +74,10 @@ export default class AppSettingsTab extends SliderSuperTab {
|
|||||||
this.buttons.folders.addEventListener('click', () => {
|
this.buttons.folders.addEventListener('click', () => {
|
||||||
appSidebarLeft.chatFoldersTab.open();
|
appSidebarLeft.chatFoldersTab.open();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.buttons.general.addEventListener('click', () => {
|
||||||
|
appSidebarLeft.generalSettingsTab.open();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public fillElements() {
|
public fillElements() {
|
||||||
|
@ -2,131 +2,18 @@ import { cancelEvent } from "../helpers/dom";
|
|||||||
import appMediaPlaybackController from "../components/appMediaPlaybackController";
|
import appMediaPlaybackController from "../components/appMediaPlaybackController";
|
||||||
import { isAppleMobile } from "../helpers/userAgent";
|
import { isAppleMobile } from "../helpers/userAgent";
|
||||||
import { isTouchSupported } from "../helpers/touchSupport";
|
import { isTouchSupported } from "../helpers/touchSupport";
|
||||||
|
import RangeSelector from "../components/rangeSelector";
|
||||||
|
|
||||||
type SUPEREVENT = MouseEvent | TouchEvent;
|
type SUPEREVENT = MouseEvent | TouchEvent;
|
||||||
|
|
||||||
export class ProgressLine {
|
export class MediaProgressLine extends RangeSelector {
|
||||||
public container: HTMLDivElement;
|
|
||||||
protected filled: HTMLDivElement;
|
|
||||||
protected seek: HTMLInputElement;
|
|
||||||
|
|
||||||
protected duration = 1;
|
|
||||||
public mousedown = false;
|
|
||||||
|
|
||||||
private events: Partial<{
|
|
||||||
//onMouseMove: ProgressLine['onMouseMove'],
|
|
||||||
onMouseDown: ProgressLine['onMouseDown'],
|
|
||||||
onMouseUp: ProgressLine['onMouseUp'],
|
|
||||||
onScrub: (scrubTime: number) => void
|
|
||||||
}> = {};
|
|
||||||
|
|
||||||
constructor(initialValue = 0) {
|
|
||||||
this.container = document.createElement('div');
|
|
||||||
this.container.classList.add('progress-line');
|
|
||||||
|
|
||||||
this.filled = document.createElement('div');
|
|
||||||
this.filled.classList.add('progress-line__filled');
|
|
||||||
|
|
||||||
const seek = this.seek = document.createElement('input');
|
|
||||||
seek.classList.add('progress-line__seek');
|
|
||||||
seek.value = '' + initialValue;
|
|
||||||
seek.setAttribute('min', '0');
|
|
||||||
//seek.setAttribute('max', '0');
|
|
||||||
seek.type = 'range';
|
|
||||||
seek.step = '0.1';
|
|
||||||
seek.max = '' + (this.duration * 1000);
|
|
||||||
|
|
||||||
if(initialValue > 0) {
|
|
||||||
this.setProgress(initialValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
//this.setListeners();
|
|
||||||
|
|
||||||
this.container.append(this.filled, seek);
|
|
||||||
}
|
|
||||||
|
|
||||||
public setHandlers(events: ProgressLine['events']) {
|
|
||||||
this.events = events;
|
|
||||||
}
|
|
||||||
|
|
||||||
onMouseMove = (e: SUPEREVENT) => {
|
|
||||||
this.mousedown && this.scrub(e);
|
|
||||||
};
|
|
||||||
|
|
||||||
onMouseDown = (e: SUPEREVENT) => {
|
|
||||||
this.scrub(e);
|
|
||||||
this.mousedown = true;
|
|
||||||
this.events?.onMouseDown && this.events.onMouseDown(e);
|
|
||||||
};
|
|
||||||
|
|
||||||
onMouseUp = (e: SUPEREVENT) => {
|
|
||||||
this.mousedown = false;
|
|
||||||
this.events?.onMouseUp && this.events.onMouseUp(e);
|
|
||||||
};
|
|
||||||
|
|
||||||
public setListeners() {
|
|
||||||
this.container.addEventListener('mousemove', this.onMouseMove);
|
|
||||||
this.container.addEventListener('mousedown', this.onMouseDown);
|
|
||||||
this.container.addEventListener('mouseup', this.onMouseUp);
|
|
||||||
|
|
||||||
if(isTouchSupported) {
|
|
||||||
this.container.addEventListener('touchmove', this.onMouseMove, {passive: true});
|
|
||||||
this.container.addEventListener('touchstart', this.onMouseDown, {passive: true});
|
|
||||||
this.container.addEventListener('touchend', this.onMouseUp, {passive: true});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public setProgress(scrubTime: number) {
|
|
||||||
this.setFilled(scrubTime);
|
|
||||||
this.seek.value = '' + (scrubTime * 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
public setFilled(scrubTime: number) {
|
|
||||||
let scaleX = scrubTime / this.duration;
|
|
||||||
scaleX = Math.max(0, Math.min(1, scaleX));
|
|
||||||
this.filled.style.transform = 'scaleX(' + scaleX + ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
protected scrub(e: SUPEREVENT) {
|
|
||||||
let offsetX: number;
|
|
||||||
if(e instanceof MouseEvent) {
|
|
||||||
offsetX = e.offsetX;
|
|
||||||
} else { // touch
|
|
||||||
const rect = (e.target as HTMLElement).getBoundingClientRect();
|
|
||||||
offsetX = e.targetTouches[0].pageX - rect.left;
|
|
||||||
}
|
|
||||||
|
|
||||||
const scrubTime = offsetX / this.container.offsetWidth * this.duration;
|
|
||||||
|
|
||||||
this.setFilled(scrubTime);
|
|
||||||
|
|
||||||
this.events?.onScrub && this.events.onScrub(scrubTime);
|
|
||||||
return scrubTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public removeListeners() {
|
|
||||||
this.container.removeEventListener('mousemove', this.onMouseMove);
|
|
||||||
this.container.removeEventListener('mousedown', this.onMouseDown);
|
|
||||||
this.container.removeEventListener('mouseup', this.onMouseUp);
|
|
||||||
|
|
||||||
if(isTouchSupported) {
|
|
||||||
this.container.removeEventListener('touchmove', this.onMouseMove);
|
|
||||||
this.container.removeEventListener('touchstart', this.onMouseDown);
|
|
||||||
this.container.removeEventListener('touchend', this.onMouseUp);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.events = {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class MediaProgressLine extends ProgressLine {
|
|
||||||
private filledLoad: HTMLDivElement;
|
private filledLoad: HTMLDivElement;
|
||||||
|
|
||||||
private stopAndScrubTimeout = 0;
|
private stopAndScrubTimeout = 0;
|
||||||
private progressRAF = 0;
|
private progressRAF = 0;
|
||||||
|
|
||||||
constructor(private media: HTMLAudioElement | HTMLVideoElement, private streamable = false) {
|
constructor(private media: HTMLAudioElement | HTMLVideoElement, private streamable = false) {
|
||||||
super();
|
super(1000 / 60 / 1000, 0, 0, 1);
|
||||||
|
|
||||||
if(streamable) {
|
if(streamable) {
|
||||||
this.filledLoad = document.createElement('div');
|
this.filledLoad = document.createElement('div');
|
||||||
@ -170,8 +57,8 @@ export class MediaProgressLine extends ProgressLine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onLoadedData = () => {
|
onLoadedData = () => {
|
||||||
this.duration = this.media.duration;
|
this.max = this.media.duration;
|
||||||
this.seek.setAttribute('max', '' + this.duration * 1000);
|
this.seek.setAttribute('max', '' + this.max);
|
||||||
};
|
};
|
||||||
|
|
||||||
onEnded = () => {
|
onEnded = () => {
|
||||||
@ -226,12 +113,13 @@ export class MediaProgressLine extends ProgressLine {
|
|||||||
//console.log('onProgress correct range:', nearestStart, end, this.media);
|
//console.log('onProgress correct range:', nearestStart, end, this.media);
|
||||||
|
|
||||||
const percents = this.media.duration ? end / this.media.duration : 0;
|
const percents = this.media.duration ? end / this.media.duration : 0;
|
||||||
this.filledLoad.style.transform = 'scaleX(' + percents + ')';
|
this.filledLoad.style.width = (percents * 100) + '%';
|
||||||
|
//this.filledLoad.style.transform = 'scaleX(' + percents + ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected setSeekMax() {
|
protected setSeekMax() {
|
||||||
this.duration = this.media.duration;
|
this.max = this.media.duration;
|
||||||
if(this.duration > 0) {
|
if(this.max > 0) {
|
||||||
this.onLoadedData();
|
this.onLoadedData();
|
||||||
} else {
|
} else {
|
||||||
this.media.addEventListener('loadeddata', this.onLoadedData);
|
this.media.addEventListener('loadeddata', this.onLoadedData);
|
||||||
@ -342,7 +230,7 @@ export default class VideoPlayer {
|
|||||||
video.muted = !video.muted;
|
video.muted = !video.muted;
|
||||||
});
|
});
|
||||||
|
|
||||||
const volumeProgress = new ProgressLine();
|
const volumeProgress = new RangeSelector(0.01, 1, 0, 1);
|
||||||
volumeProgress.setListeners();
|
volumeProgress.setListeners();
|
||||||
volumeProgress.setHandlers({
|
volumeProgress.setHandlers({
|
||||||
onScrub: currentTime => {
|
onScrub: currentTime => {
|
||||||
|
@ -446,30 +446,21 @@
|
|||||||
|
|
||||||
// * for audio
|
// * for audio
|
||||||
.progress-line {
|
.progress-line {
|
||||||
|
--height: 2px;
|
||||||
|
--border-radius: 4px;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
margin-top: -1px;
|
margin-top: -1px;
|
||||||
|
|
||||||
&__filled {
|
|
||||||
background-color: #0089ff;
|
|
||||||
transform-origin: left;
|
|
||||||
height: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__loaded {
|
&__loaded {
|
||||||
background-color: #cacaca;
|
background-color: #cacaca;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__seek {
|
&__seek {
|
||||||
height: 2px;
|
--thumb-size: 12px;
|
||||||
|
--thumb-color: #0089ff;
|
||||||
//background-color: #e6ecf0;
|
//background-color: #e6ecf0;
|
||||||
background: rgba(193, 207, 220, 0.39);
|
background-color: rgba(193, 207, 220, .39);
|
||||||
|
|
||||||
&::-webkit-slider-thumb {
|
|
||||||
height: 12px;
|
|
||||||
width: 12px;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1964,11 +1964,8 @@ $bubble-margin: .25rem;
|
|||||||
}
|
}
|
||||||
|
|
||||||
&__seek {
|
&__seek {
|
||||||
background: rgba(124, 195, 107, .52);
|
--thumb-color: #47aa41;
|
||||||
|
background-color: rgba(124, 195, 107, .52);
|
||||||
&::-webkit-slider-thumb {
|
|
||||||
background: #47aa41;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,28 +134,18 @@
|
|||||||
transition: all .3s;
|
transition: all .3s;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
direction: ltr;
|
direction: ltr;
|
||||||
border-radius: 0 0 5px 5px;
|
|
||||||
z-index: 6;
|
z-index: 6;
|
||||||
|
|
||||||
.progress-line {
|
.progress-line {
|
||||||
margin: 0 16px;
|
margin: 0 16px;
|
||||||
height: 5px;
|
border-radius: var(--border-radius);
|
||||||
background: rgba(255, 255, 255, 0.38);
|
|
||||||
border-radius: 4px;
|
|
||||||
overflow: visible;
|
|
||||||
|
|
||||||
&__filled {
|
&__filled {
|
||||||
background: #63a2e3;
|
background: #63a2e3;
|
||||||
transform-origin: left;
|
|
||||||
border-radius: 4px;
|
|
||||||
height: 5px;
|
|
||||||
transform: scaleX(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__loaded {
|
&__loaded, & {
|
||||||
background: rgba(255, 255, 255, 0.38);
|
background: rgba(255, 255, 255, .38);
|
||||||
left: 11px;
|
|
||||||
width: calc(100% - 11px);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -253,11 +243,12 @@
|
|||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=range]::-webkit-slider-thumb {
|
&__seek {
|
||||||
height: 15px;
|
--thumb-size: 15px;
|
||||||
width: 15px;
|
|
||||||
border-radius: 16px;
|
&::-webkit-slider-thumb {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,16 +272,23 @@ video::-webkit-media-controls-enclosure {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.progress-line {
|
.progress-line {
|
||||||
|
--height: 5px;
|
||||||
|
--border-radius: 6px;
|
||||||
|
height: var(--height);
|
||||||
position: relative;
|
position: relative;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&__seek {
|
&__seek {
|
||||||
|
--thumb-size: 13px;
|
||||||
|
--thumb-color: #63a2e3;
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
-moz-appearance: none;
|
-moz-appearance: none;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
height: 4.5px;
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
@ -310,18 +308,39 @@ video::-webkit-media-controls-enclosure {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border-radius: 1.3px;
|
border-radius: 1.3px;
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
transition: all 0.4s ease;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&::-webkit-slider-thumb {
|
&::-webkit-slider-thumb {
|
||||||
height: 15px;
|
height: var(--thumb-size);
|
||||||
width: 15px;
|
width: var(--thumb-size);
|
||||||
border-radius: 16px;
|
border-radius: 50%;
|
||||||
background: #63a2e3;
|
background-color: var(--thumb-color);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
margin-left: -1px;
|
|
||||||
border: none;
|
border: none;
|
||||||
|
//margin-left: -.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-moz-range-thumb {
|
||||||
|
height: var(--thumb-size);
|
||||||
|
width: var(--thumb-size);
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: var(--thumb-color);
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
border: none;
|
||||||
|
//margin-left: -.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-ms-thumb {
|
||||||
|
height: var(--thumb-size);
|
||||||
|
width: var(--thumb-size);
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: var(--thumb-color);
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
border: none;
|
||||||
|
//margin-left: -.5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&::-moz-range-track {
|
&::-moz-range-track {
|
||||||
@ -330,33 +349,20 @@ video::-webkit-media-controls-enclosure {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
border-radius: 1.3px;
|
//border-radius: 1.3px;
|
||||||
}
|
|
||||||
|
|
||||||
&::-moz-range-thumb {
|
|
||||||
height: 14px;
|
|
||||||
width: 14px;
|
|
||||||
border-radius: 50px;
|
|
||||||
border: 1px solid #63a2e3;
|
|
||||||
background: #63a2e3;
|
|
||||||
cursor: pointer;
|
|
||||||
margin-top: 5px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__seek {
|
&__filled {
|
||||||
position: absolute;
|
padding-right: 1px; // * need because there is border-radius
|
||||||
top: 0;
|
max-width: 100%;
|
||||||
width: 100%;
|
|
||||||
cursor: pointer;
|
|
||||||
margin: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__loaded {
|
&__seek, &__filled, &__loaded {
|
||||||
|
border-radius: var(--border-radius);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 12px;
|
height: 100%;
|
||||||
top: 0;
|
top: 0;
|
||||||
width: calc(100% - 12px);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -879,3 +879,43 @@
|
|||||||
padding: 0px 0 7px;
|
padding: 0px 0 7px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sidebar-left-section {
|
||||||
|
padding: .5rem 0 1rem;
|
||||||
|
|
||||||
|
&-content {
|
||||||
|
padding: 0 1.5rem;
|
||||||
|
|
||||||
|
@include respond-to(handhelds) {
|
||||||
|
padding: 0 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-name {
|
||||||
|
color: #707579;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.range-setting-selector {
|
||||||
|
&-details {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-line {
|
||||||
|
--height: 2px;
|
||||||
|
--border-radius: 4px;
|
||||||
|
background-color: #e6ecf0;
|
||||||
|
|
||||||
|
&__filled {
|
||||||
|
background-color: #3390ec;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__seek {
|
||||||
|
--thumb-color: #3390ec;
|
||||||
|
--thumb-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user