Browse Source

audiomessages & new player

master
Eduard Kuzmenko 4 years ago
parent
commit
956a260a27
  1. 97
      src/components/wrappers.ts
  2. 18
      src/lib/appManagers/appSidebarRight.ts
  3. 516
      src/lib/ckin.js
  4. 26
      src/scss/partials/_chat.scss
  5. 109
      src/scss/partials/_ckin.scss
  6. 25
      src/scss/style.scss

97
src/components/wrappers.ts

@ -29,7 +29,8 @@ export type MTDocument = {
h?: number, h?: number,
w?: number, w?: number,
file_name?: string, file_name?: string,
file?: File file?: File,
duration?: number
}; };
export type MTPhotoSize = { export type MTPhotoSize = {
@ -235,24 +236,56 @@ export function wrapDocument(doc: MTDocument, withTime = false): HTMLDivElement
return docDiv; return docDiv;
} }
let lastAudioToggle: HTMLDivElement = null;
export function wrapAudio(doc: MTDocument, withTime = false): HTMLDivElement { export function wrapAudio(doc: MTDocument, withTime = false): HTMLDivElement {
let div = document.createElement('div'); let div = document.createElement('div');
div.classList.add('audio'); div.classList.add('audio');
let duration = doc.duration;
// @ts-ignore
let durationStr = String(duration | 0).toHHMMSS(true);
div.innerHTML = ` div.innerHTML = `
<div class="audio-toggle audio-ico tgico-largeplay"></div> <div class="audio-toggle audio-ico tgico-largeplay"></div>
<div class="audio-download"><div class="tgico-download"></div></div> <div class="audio-download"><div class="tgico-download"></div></div>
<div class="audio-title"></div> <div class="audio-time">${durationStr}</div>
<div class="audio-subtitle"></div>
<div class="audio-time"></div>
`; `;
console.log('wrapping audio', doc); console.log('wrapping audio', doc, doc.attributes[0].waveform);
let timeDiv = div.lastElementChild as HTMLDivElement;
let downloadDiv = div.querySelector('.audio-download') as HTMLDivElement; let downloadDiv = div.querySelector('.audio-download') as HTMLDivElement;
let preloader: ProgressivePreloader; let preloader: ProgressivePreloader;
let promise: CancellablePromise<Blob>; let promise: CancellablePromise<Blob>;
let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.classList.add('audio-waveform');
svg.setAttributeNS(null, 'width', '250');
svg.setAttributeNS(null, 'height', '23');
svg.setAttributeNS(null, 'viewBox', '0 0 250 23');
div.insertBefore(svg, div.lastElementChild);
let wave = doc.attributes[0].waveform as Uint8Array;
let index = 0;
for(let uint8 of wave) {
let percents = uint8 / 255;
let height = 23 * percents;
if(/* !height || */height < 2) {
height = 2;
}
svg.insertAdjacentHTML('beforeend', `
<rect x="${index * 4}" y="${23 - height}" width="2" height="${height}" rx="1" ry="1"></rect>
`);
++index;
}
let onClick = () => { let onClick = () => {
if(!promise) { if(!promise) {
if(downloadDiv.classList.contains('downloading')) { if(downloadDiv.classList.contains('downloading')) {
@ -276,9 +309,57 @@ export function wrapAudio(doc: MTDocument, withTime = false): HTMLDivElement {
source.type = doc.mime_type; source.type = doc.mime_type;
div.removeEventListener('click', onClick); div.removeEventListener('click', onClick);
div.querySelector('.audio-toggle').addEventListener('click', () => { let toggle = div.querySelector('.audio-toggle') as HTMLDivElement;
audio.currentTime = 0;
audio.play(); let interval = 0;
toggle.addEventListener('click', () => {
if(audio.paused) {
if(lastAudioToggle && lastAudioToggle.classList.contains('tgico-largepause')) {
lastAudioToggle.click();
}
audio.currentTime = 0;
audio.play();
lastAudioToggle = toggle;
toggle.classList.remove('tgico-largeplay');
toggle.classList.add('tgico-largepause');
(Array.from(svg.children) as HTMLElement[]).forEach(node => node.classList.remove('active'));
let lastIndex = 0;
interval = setInterval(() => {
if(lastIndex >= svg.childElementCount) {
clearInterval(interval);
return;
}
// @ts-ignore
timeDiv.innerText = String(audio.currentTime | 0).toHHMMSS(true);
//svg.children[lastIndex].setAttributeNS(null, 'fill', '#000');
svg.children[lastIndex].classList.add('active');
++lastIndex;
//console.log('lastIndex:', lastIndex, audio.currentTime);
}, duration * 1000 / svg.childElementCount | 0/* 63 * duration / 10 */);
} else {
audio.pause();
toggle.classList.add('tgico-largeplay');
toggle.classList.remove('tgico-largepause');
clearInterval(interval);
}
});
audio.addEventListener('ended', () => {
toggle.classList.add('tgico-largeplay');
toggle.classList.remove('tgico-largepause');
clearInterval(interval);
// @ts-ignore
timeDiv.innerText = String(audio.currentTime | 0).toHHMMSS(true);
}); });
audio.append(source); audio.append(source);

18
src/lib/appManagers/appSidebarRight.ts

@ -112,7 +112,7 @@ class AppSidebarRight {
this.prevTabID = id; this.prevTabID = id;
this.log('setVirtualContainer', id, this.sharedMediaSelected); //this.log('setVirtualContainer', id, this.sharedMediaSelected);
this.sidebarScroll.setVirtualContainer(this.sharedMediaSelected); this.sidebarScroll.setVirtualContainer(this.sharedMediaSelected);
if(this.savedVirtualStates[id]) { if(this.savedVirtualStates[id]) {
@ -169,7 +169,7 @@ class AppSidebarRight {
let media = Array.from(this.sharedMediaSelected.childNodes).slice(-15); let media = Array.from(this.sharedMediaSelected.childNodes).slice(-15);
for(let div of media) { for(let div of media) {
if(isElementInViewport(div)) { if(isElementInViewport(div)) {
this.log('Will load more media'); //this.log('Will load more media');
this.loadSidebarMedia(true); this.loadSidebarMedia(true);
break; break;
@ -256,12 +256,12 @@ class AppSidebarRight {
let media = message.media.photo || message.media.document || (message.media.webpage && message.media.webpage.document); let media = message.media.photo || message.media.document || (message.media.webpage && message.media.webpage.document);
if(!media) { if(!media) {
this.log('no media!', message); //this.log('no media!', message);
break; break;
} }
if(media._ == 'document' && media.type != 'video'/* && media.type != 'gif' */) { if(media._ == 'document' && media.type != 'video'/* && media.type != 'gif' */) {
this.log('broken video', media); //this.log('broken video', media);
break; break;
} }
@ -334,7 +334,7 @@ class AppSidebarRight {
let previewDiv = document.createElement('div'); let previewDiv = document.createElement('div');
previewDiv.classList.add('preview'); previewDiv.classList.add('preview');
this.log('wrapping webpage', webpage); //this.log('wrapping webpage', webpage);
if(webpage.photo) { if(webpage.photo) {
let load = () => appPhotosManager.preloadPhoto(webpage.photo.id, appPhotosManager.choosePhotoSize(webpage.photo, 380, 0)) let load = () => appPhotosManager.preloadPhoto(webpage.photo.id, appPhotosManager.choosePhotoSize(webpage.photo, 380, 0))
@ -394,7 +394,7 @@ class AppSidebarRight {
} */ } */
default: default:
console.warn('death is my friend', message); //console.warn('death is my friend', message);
break; break;
} }
}); });
@ -416,7 +416,7 @@ class AppSidebarRight {
this.loadSidebarMediaPromises = {}; this.loadSidebarMediaPromises = {};
this.lastSharedMediaDiv = document.createElement('div'); this.lastSharedMediaDiv = document.createElement('div');
this.log('fillProfileElements'); //this.log('fillProfileElements');
this.savedVirtualStates = {}; this.savedVirtualStates = {};
this.prevTabID = -1; this.prevTabID = -1;
@ -483,7 +483,7 @@ class AppSidebarRight {
setText(userFull.rAbout, this.profileElements.bio); setText(userFull.rAbout, this.profileElements.bio);
} }
this.log('userFull', userFull); //this.log('userFull', userFull);
if(userFull.pinned_msg_id) { // request pinned message if(userFull.pinned_msg_id) { // request pinned message
appImManager.pinnedMsgID = userFull.pinned_msg_id; appImManager.pinnedMsgID = userFull.pinned_msg_id;
@ -499,7 +499,7 @@ class AppSidebarRight {
return; return;
} }
this.log('chatInfo res 2:', chatFull); //this.log('chatInfo res 2:', chatFull);
if(chatFull.about) { if(chatFull.about) {
setText(RichTextProcessor.wrapRichText(chatFull.about), this.profileElements.bio); setText(RichTextProcessor.wrapRichText(chatFull.about), this.profileElements.bio);

516
src/lib/ckin.js

@ -1,280 +1,328 @@
String.prototype.toHHMMSS = function() { (function () {
if (typeof NodeList.prototype.forEach === "function") return false;
NodeList.prototype.forEach = Array.prototype.forEach;
})();
String.prototype.toHHMMSS = function(leadZero) {
let sec_num = parseInt(this, 10); let sec_num = parseInt(this, 10);
let hours = Math.floor(sec_num / 3600); let hours = Math.floor(sec_num / 3600);
let minutes = Math.floor((sec_num - (hours * 3600)) / 60); let minutes = Math.floor((sec_num - (hours * 3600)) / 60);
let seconds = sec_num - (hours * 3600) - (minutes * 60); let seconds = sec_num - (hours * 3600) - (minutes * 60);
if(hours < 10) hours = "0" + hours; if(hours < 10) hours = "0" + hours;
if(minutes < 10) minutes = minutes; if(minutes < 10) minutes = leadZero ? "0" + minutes : minutes;
if(seconds < 10) seconds = "0" + seconds; if(seconds < 10) seconds = "0" + seconds;
return minutes + ':' + seconds; return minutes + ':' + seconds;
} }
function stylePlayer(player, video) { function stylePlayer(player, video) {
let skin = attachSkin(video.dataset.ckin); let skin = attachSkin(video.dataset.ckin);
player.classList.add(skin); player.classList.add(skin);
let overlay = video.dataset.overlay;
addOverlay(player, overlay);
let html = buildControls(skin);
player.insertAdjacentHTML('beforeend', html);
var stopAndScrubTimeout = 0; let html = buildControls(skin);
player.insertAdjacentHTML('beforeend', html);
if(skin === 'default') { let updateInterval = 0;
var progress = player.querySelector('.progress');; let elapsed = 0;
var progressBar = player.querySelector('.progress__filled'); let prevTime = 0;
var toggle = player.querySelectorAll('.toggle');
var fullScreenButton = player.querySelector('.fullscreen'); if (skin === 'default') {
var seek = player.querySelector('#seek'); var progress = player.querySelector('.progress');;
var timeElapsed = player.querySelector('#time-elapsed'); var progressBar = player.querySelector('.progress__filled');
var timeDuration = player.querySelector('#time-duration'); var toggle = player.querySelectorAll('.toggle');
seek.setAttribute('max', video.duration); var fullScreenButton = player.querySelector('.fullscreen');
timeDuration.innerHTML = String(video.duration | 0).toHHMMSS(); var seek = player.querySelector('#seek');
var timeElapsed = player.querySelector('#time-elapsed');
toggle.forEach((button) => { var timeDuration = player.querySelector('#time-duration');
return button.addEventListener('click', () => { timeDuration.innerHTML = String(video.duration | 0).toHHMMSS();
togglePlay(video, player);
}); toggle.forEach((button) => {
}); return button.addEventListener('click', () => {
togglePlay(video, player);
video.addEventListener('click', function() { });
togglePlay(this, player); });
});
video.addEventListener('click', function () {
video.addEventListener('play', function() { togglePlay(this, player);
updateButton(this, toggle); });
});
video.addEventListener('play', function () {
video.addEventListener('pause', function() { updateButton(this, toggle);
updateButton(this, toggle); updateInterval = setInterval(function () {
}); if (video.paused) return; //chtob ne prigal seek pri peremotke
//elapsed += 0.02; // Increase with timer interval
let mousedown = false; if (video.currentTime != prevTime) {
progress.addEventListener('mousemove', (e) => { elapsed = video.currentTime; // Update if getCurrentTime was changed
return mousedown && scrub(e, video, progress); prevTime = video.currentTime;
}); }
progress.addEventListener('mousedown', (e) => { let scaleX = (elapsed / video.duration);
//console.log(video.currentTime); progressBar.style.transform = 'scaleX(' + scaleX + ')';
scrub(e, video, progress, progressBar); if (video.paused) clearInterval(updateInterval);
//Таймер для того, чтобы стопать видео, если зажал мышку и не отпустил клик seek.value = video.currentTime * 1000;
stopAndScrubTimeout = setTimeout(function() { }, 20);
togglePlay(video, player, 1); });
}, 150);
video.addEventListener('ended', function () {
return mousedown = true; progressBar.style.transform = 'scaleX(1)';
}); seek.value = video.currentTime * 1000;
progress.addEventListener('mouseup', () => { });
clearTimeout(stopAndScrubTimeout);
togglePlay(video, player, 0); video.addEventListener('pause', function () {
return mousedown = false; updateButton(this, toggle);
}); clearInterval(updateInterval);
fullScreenButton.addEventListener('click', (e) => { });
return toggleFullScreen(player, fullScreenButton);
}); video.addEventListener('dblclick', function () {
addListenerMulti(player, 'webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange', (e) => { return toggleFullScreen(player, fullScreenButton);
return onFullScreen(e, player); })
});
} let mousedown = false;
let stopAndScrubTimeout = 0;
if(skin === 'circle') { progress.addEventListener('mousemove', (e) => {
let wrapper = document.createElement('div'); return mousedown && scrub(e, video, progress, progressBar);
wrapper.classList.add('circle-time-left'); });
video.parentNode.insertBefore(wrapper, video); progress.addEventListener('mousedown', (e) => {
wrapper.innerHTML = '<div class="circle-time"></div><div class="iconVolume tgico-nosound"></div>'; scrub(e, video, progress, progressBar, updateInterval);
//Таймер для того, чтобы стопать видео, если зажал мышку и не отпустил клик
var circle = player.querySelector('.progress-ring__circle'); stopAndScrubTimeout = setTimeout(function () {
var radius = circle.r.baseVal.value; togglePlay(video, player, 1);
var circumference = 2 * Math.PI * radius; }, 150);
var timeDuration = player.querySelector('.circle-time');
var iconVolume = player.querySelector('.iconVolume'); return mousedown = true;
circle.style.strokeDasharray = `${circumference} ${circumference}`; });
circle.style.strokeDashoffset = circumference; progress.addEventListener('mouseup', () => {
circle.addEventListener('click', () => { if (typeof stopAndScrubTimeout !== 'undefined') {
togglePlay(video, player); clearTimeout(stopAndScrubTimeout);
}); }
togglePlay(video, player, 0);
video.addEventListener('play', () => { return mousedown = false;
iconVolume.style.display = 'none'; });
}); fullScreenButton.addEventListener('click', (e) => {
return toggleFullScreen(player, fullScreenButton);
video.addEventListener('pause', () => { });
iconVolume.style.display = ''; addListenerMulti(player, 'webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange', (e) => {
}); return onFullScreen(e, player);
} });
}
//Для хрома
timeDuration.innerHTML = String(video.duration | 0).toHHMMSS(); if (skin === 'circle') {
if(skin === 'default') seek.setAttribute('max', video.duration); let wrapper = document.createElement('div');
//Для Opera / Safari / IE wrapper.classList.add('circle-time-left');
video.addEventListener('loadeddata', function() { video.parentNode.insertBefore(wrapper, video);
timeDuration.innerHTML = String(video.duration | 0).toHHMMSS(); wrapper.innerHTML = '<div class="circle-time"></div><div class="iconVolume tgico-nosound"></div>';
if(skin === 'default') seek.setAttribute('max', video.duration);
}) var circle = player.querySelector('.progress-ring__circle');
var radius = circle.r.baseVal.value;
video.addEventListener('timeupdate', function() { var circumference = 2 * Math.PI * radius;
handleProgress(this, skin, timeDuration, circumference, circle, progressBar, seek, timeElapsed); var timeDuration = player.querySelector('.circle-time');
}); var iconVolume = player.querySelector('.iconVolume');
circle.style.strokeDasharray = circumference + ' ' + circumference;
circle.style.strokeDashoffset = circumference;
circle.addEventListener('click', () => {
togglePlay(video, player);
});
video.addEventListener('play', () => {
iconVolume.style.display = 'none';
updateInterval = setInterval(function () {
//elapsed += 0.02; // Increase with timer interval
if (video.currentTime != prevTime) {
elapsed = video.currentTime; // Update if getCurrentTime was changed
prevTime = video.currentTime;
}
let offset = circumference - elapsed / video.duration * circumference;
circle.style.strokeDashoffset = offset;
if (video.paused) clearInterval(updateInterval);
}, 20);
});
video.addEventListener('pause', () => {
iconVolume.style.display = '';
});
}
//Для хрома
timeDuration.innerHTML = String(Math.round(video.duration)).toHHMMSS();
if (skin === 'default') seek.setAttribute('max', video.duration * 1000);
//Для Opera / Safari / IE
video.addEventListener('loadeddata', function () {
timeDuration.innerHTML = String(Math.round(video.duration)).toHHMMSS();
if (skin === 'default') seek.setAttribute('max', video.duration * 1000);
})
video.addEventListener('timeupdate', function () {
updateInterval = handleProgress(this, skin, timeDuration, circumference, circle, progressBar, seek, timeElapsed, updateInterval);
});
} }
function showControls(video) { function showControls(video) {
video.setAttribute("controls", "controls"); video.setAttribute("controls", "controls");
} }
function togglePlay(video, player, stop) { function togglePlay(video, player, stop) {
if(stop == 1) { if (stop == 1) {
video['pause'](); video['pause']();
player.classList.remove('is-playing'); player.classList.remove('is-playing');
return; return;
} else if(stop == 0) { } else if (stop == 0) {
video['play'](); video['play']();
player.classList.add('is-playing'); player.classList.add('is-playing');
return; return;
} }
let method = video.paused ? 'play' : 'pause'; let method = video.paused ? 'play' : 'pause';
video[method](); video[method]();
video.paused ? player.classList.remove('is-playing') : player.classList.add('is-playing'); video.paused ? player.classList.remove('is-playing') : player.classList.add('is-playing');
} }
function updateButton(video, toggle) { function updateButton(video, toggle) {
let icon = video.paused ? 'tgico-play' : 'tgico-pause'; let icon = video.paused ? 'tgico-play' : 'tgico-pause';
toggle.forEach((button) => { toggle.forEach((button) => {
button.classList.remove('tgico-play', 'tgico-pause'); button.classList.remove('tgico-play', 'tgico-pause');
button.classList.add(icon); button.classList.add(icon);
}); });
} }
function handleProgress(video, skin, timeDuration, circumference, circle, progressBar, seek, timeElapsed) { function handleProgress(video, skin, timeDuration, circumference, circle, progressBar, seek, timeElapsed, updateInterval, mousemove) {
let percent = video.currentTime / video.duration * 100; clearInterval(updateInterval);
if(skin === 'default') { let elapsed = 0;
progressBar.style.width = percent + '%'; let prevTime = 0;
seek.value = video.currentTime; if (skin === 'default') {
timeElapsed.innerHTML = String(video.currentTime | 0).toHHMMSS(); updateInterval = setInterval(function () {
} else if(skin === 'circle') { if (video.paused) return;
let timeLeft = String((video.duration - video.currentTime) | 0).toHHMMSS(); if (video.currentTime != prevTime) {
let offset = circumference - percent / 100 * circumference; elapsed = video.currentTime; // Update if getCurrentTime was changed
circle.style.strokeDashoffset = offset; prevTime = video.currentTime;
if(timeLeft != 0 | 0) timeDuration.innerHTML = timeLeft; }
} let scaleX = (elapsed / video.duration);
progressBar.style.transform = 'scaleX(' + scaleX + ')';
if (video.paused) clearInterval(updateInterval);
seek.value = video.currentTime * 1000;
}, 20);
timeElapsed.innerHTML = String(video.currentTime | 0).toHHMMSS();
return updateInterval;
} else if (skin === 'circle') {
updateInterval = setInterval(function () {
if (video.currentTime != prevTime) {
elapsed = video.currentTime; // Update if getCurrentTime was changed
prevTime = video.currentTime;
}
let offset = circumference - elapsed / video.duration * circumference;
circle.style.strokeDashoffset = offset;
if (video.paused) clearInterval(updateInterval);
}, 20);
let timeLeft = String((video.duration - video.currentTime) | 0).toHHMMSS();
if (timeLeft != 0 | 0) timeDuration.innerHTML = timeLeft;
}
} }
function scrub(e, video, progress) { function scrub(e, video, progress, progressBar) {
let scrubTime = e.offsetX / progress.offsetWidth * video.duration; let scrubTime = e.offsetX / progress.offsetWidth * video.duration;
video.currentTime = scrubTime; video.currentTime = scrubTime;
let scaleX = scrubTime / video.duration;
if (scaleX > 1) scaleX = 1;
if (scaleX < 0) scaleX = 0;
progressBar.style.transform = 'scaleX(' + scaleX + ')';
} }
export function wrapPlayer(video) { export function wrapPlayer(video) {
let wrapper = document.createElement('div'); let wrapper = document.createElement('div');
wrapper.classList.add('ckin__player'); wrapper.classList.add('ckin__player');
video.parentNode.insertBefore(wrapper, video); video.parentNode.insertBefore(wrapper, video);
wrapper.appendChild(video); wrapper.appendChild(video);
stylePlayer(wrapper, video); stylePlayer(wrapper, video);
return wrapper; return wrapper;
} }
function buildControls(skin) { function buildControls(skin) {
let html = []; let html = [];
if(skin === 'default') { if (skin === 'default') {
html.push('<button class="' + skin + '__button--big toggle tgico-largeplay" title="Toggle Play"></button>'); html.push('<button class="' + skin + '__button--big toggle tgico-largeplay" title="Toggle Play"></button>');
html.push('<div class="' + skin + '__controls ckin__controls">'); html.push('<div class="' + skin + '__gradient-bottom ckin__controls"></div>');
html.push('<div class="progress">', html.push('<div class="' + skin + '__controls ckin__controls">');
'<div class="progress__filled"></div><input class="seek" id="seek" value="0" min="0" type="range" step="0.1" max="0">', html.push('<div class="progress">',
'</div>', '<div class="progress__filled"></div><input class="seek" id="seek" value="0" min="0" type="range" step="0.1" max="0">',
'<div class="bottom-controls">', '</div>',
'<div class="left-controls"><button class="' + skin + '__button toggle tgico-play" title="Toggle Video"></button>', '<div class="bottom-controls">',
'<div class="time">', '<div class="left-controls"><button class="' + skin + '__button toggle tgico-play" title="Toggle Video"></button>',
'<time id="time-elapsed">0:00</time>', '<div class="time">',
'<span> / </span>', '<time id="time-elapsed">0:00</time>',
'<time id="time-duration">0:00</time>', '<span> / </span>',
'</div>', '<time id="time-duration">0:00</time>',
'</div>', '</div>',
'<div class="right-controls"><button class="' + skin + '__button fullscreen tgico-fullscreen" title="Full Screen"></button></div></div>'); '</div>',
html.push('</div>'); '<div class="right-controls"><button class="' + skin + '__button fullscreen tgico-fullscreen" title="Full Screen"></button></div></div>');
} else if(skin === 'circle') { html.push('</div>');
html.push('<svg class="progress-ring" width="200px" height="200px">', } else if (skin === 'circle') {
'<circle class="progress-ring__circle" stroke="white" stroke-opacity="0.3" stroke-width="3.5" cx="100" cy="100" r="93" fill="transparent"/>', html.push('<svg class="progress-ring" width="200px" height="200px">',
'</svg>'); '<circle class="progress-ring__circle" stroke="white" stroke-opacity="0.3" stroke-width="3.5" cx="100" cy="100" r="93" fill="transparent" transform="rotate(-90, 100, 100)"/>',
} '</svg>');
}
return html.join('');
}
function attachSkin(skin) { return html.join('');
console.log("skin: " + skin);
if(typeof skin != 'undefined' && skin != '') {
return skin;
} else {
return 'default';
}
} }
function addOverlay(player, overlay) { function attachSkin(skin) {
if(overlay == 1) { console.log("skin: " + skin);
player.classList.add('ckin__overlay'); if (typeof skin != 'undefined' && skin != '') {
} else { return skin;
return; } else {
} return 'default';
}
} }
function toggleFullScreen(player, fullScreenButton) { function toggleFullScreen(player, fullScreenButton) {
// alternative standard method // alternative standard method
if(!document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) { if (!document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) {
player.classList.add('ckin__fullscreen'); player.classList.add('ckin__fullscreen');
if(player.requestFullscreen) { if (player.requestFullscreen) {
player.requestFullscreen(); player.requestFullscreen();
} else if(player.mozRequestFullScreen) { } else if (player.mozRequestFullScreen) {
player.mozRequestFullScreen(); // Firefox player.mozRequestFullScreen(); // Firefox
} else if(player.webkitRequestFullscreen) { } else if (player.webkitRequestFullscreen) {
player.webkitRequestFullscreen(); // Chrome and Safari player.webkitRequestFullscreen(); // Chrome and Safari
} else if(player.msRequestFullscreen) { } else if (player.msRequestFullscreen) {
player.msRequestFullscreen(); player.msRequestFullscreen();
} }
fullScreenButton.classList.remove('tgico-fullscreen'); fullScreenButton.classList.remove('tgico-fullscreen');
fullScreenButton.classList.add('tgico-smallscreen'); fullScreenButton.classList.add('tgico-smallscreen');
fullScreenButton.setAttribute('title', 'Exit Full Screen'); fullScreenButton.setAttribute('title', 'Exit Full Screen');
} else { } else {
player.classList.remove('ckin__fullscreen'); player.classList.remove('ckin__fullscreen');
if(document.cancelFullScreen) { if (document.cancelFullScreen) {
document.cancelFullScreen(); document.cancelFullScreen();
} else if(document.mozCancelFullScreen) { } else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen(); document.mozCancelFullScreen();
} else if(document.webkitCancelFullScreen) { } else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen(); document.webkitCancelFullScreen();
} else if(document.msExitFullscreen) { } else if (document.msExitFullscreen) {
document.msExitFullscreen(); document.msExitFullscreen();
} }
fullScreenButton.classList.remove('tgico-smallscreen'); fullScreenButton.classList.remove('tgico-smallscreen');
fullScreenButton.classList.add('tgico-fullscreen'); fullScreenButton.classList.add('tgico-fullscreen');
fullScreenButton.setAttribute('title', 'Full Screen'); fullScreenButton.setAttribute('title', 'Full Screen');
} }
} }
function onFullScreen(e, player) { function onFullScreen(e, player) {
let isFullscreenNow = document.webkitFullscreenElement !== null; let isFullscreenNow = document.webkitFullscreenElement !== null;
if(!isFullscreenNow) { if (!isFullscreenNow) {
player.classList.remove('ckin__fullscreen'); player.classList.remove('ckin__fullscreen');
} else {
/* let el = player.querySelector('.fullscreen'); }
el.classList.remove('tgico-smallscreen');
el.classList.add('tgico-fullscreen'); */
} else {
// player.querySelector('.fullscreen').innerHTML = iconExpand;
}
} }
function addListenerMulti(element, eventNames, listener) { function addListenerMulti(element, eventNames, listener) {
let events = eventNames.split(' '); let events = eventNames.split(' ');
for (let i = 0, iLen = events.length; i < iLen; i++) { for (let i = 0, iLen = events.length; i < iLen; i++) {
element.addEventListener(events[i], listener, false); element.addEventListener(events[i], listener, false);
} }
} }

26
src/scss/partials/_chat.scss

@ -239,6 +239,12 @@
} }
} }
&:not(.hide-name) {
.audio {
margin: 4px 0;
}
}
&:hover { &:hover {
.forward { .forward {
opacity: 1; opacity: 1;
@ -897,6 +903,26 @@
left: auto; left: auto;
right: -2.5rem; right: -2.5rem;
} }
.audio {
&-waveform {
rect {
fill: #B8DDA9;
&.active {
fill: #68AB5A;
}
}
}
&-time {
color: #68AB5A;
}
&-toggle, &-download {
background-color: #68AB5A;
}
}
} }
} }

109
src/scss/partials/_ckin.scss

@ -1,16 +1,3 @@
/*!
ckin v0.0.1: Custom HTML5 Video Player Skins.
(c) 2017
MIT License
git+https://github.com/hunzaboy/ckin.git
*/
/* video {
width: 100%;
height: auto;
cursor: pointer;
} */
.ckin { .ckin {
&__player { &__player {
letter-spacing: 0.02em; letter-spacing: 0.02em;
@ -65,7 +52,6 @@
left: 0; left: 0;
bottom: 0; bottom: 0;
right: 0; right: 0;
//border-radius: 5px;
transition: opacity .2s; transition: opacity .2s;
opacity: 1; opacity: 1;
visibility: visible; visibility: visible;
@ -87,7 +73,6 @@
color: #fff; color: #fff;
outline: 0; outline: 0;
padding: 3px 10px 6px 10px; padding: 3px 10px 6px 10px;
/* padding: 6px 10px 6px 10px; */
cursor: pointer; cursor: pointer;
font-size: 24px; font-size: 24px;
line-height: 1; line-height: 1;
@ -134,16 +119,40 @@
right: 0; right: 0;
left: 0; left: 0;
transition: all .3s; transition: all .3s;
/* background: linear-gradient(to top, rgba(0, 0, 0, 0.65) 0%, transparent 100%); */
/* font-size: 32px; */
text-align: left; text-align: left;
direction: ltr; direction: ltr;
/* padding-top: 7px; */
border-radius: 0 0 5px 5px; border-radius: 0 0 5px 5px;
z-index: 3; z-index: 6;
} }
} }
.default__gradient-bottom {
height: 49px;
// padding-top: 49px;
padding-top: 93px;
bottom: 0;
z-index: 2;
background-position: bottom;
width: 100%;
position: absolute;
background-repeat: repeat-x;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAADGCAYAAAAT+OqFAAAAdklEQVQoz42QQQ7AIAgEF/T/D+kbq/RWAlnQyyazA4aoAB4FsBSA/bFjuF1EOL7VbrIrBuusmrt4ZZORfb6ehbWdnRHEIiITaEUKa5EJqUakRSaEYBJSCY2dEstQY7AuxahwXFrvZmWl2rh4JZ07z9dLtesfNj5q0FU3A5ObbwAAAABJRU5ErkJggg==);
-moz-transition: all .3s;
-webkit-transition: all .3s;
transition: all .3s;
pointer-events: none;
}
.default.is-playing .default__gradient-bottom {
-ms-transform: translateY(50px);
transform: translateY(50px);
}
.default.is-playing:hover .default__gradient-bottom {
-ms-transform: translateY(0px);
transform: translateY(0px);
}
.default.is-playing:before { .default.is-playing:before {
opacity: 0; opacity: 0;
visibility: hidden; visibility: hidden;
@ -168,9 +177,7 @@
.default .progress { .default .progress {
position: relative; position: relative;
display: -ms-flexbox; margin: 0 16px;
display: flex;
margin: 0 8px;
height: 5px; height: 5px;
transition: height 0.3s; transition: height 0.3s;
background: rgba(255, 255, 255, 0.38); background: rgba(255, 255, 255, 0.38);
@ -180,13 +187,11 @@
} }
.default .progress__filled { .default .progress__filled {
width: 0%;
background: #63a2e3; background: #63a2e3;
/* -ms-flex: 0; transform-origin: left;
flex: 0;
-ms-flex-preferred-size: 0%;
flex-basis: 0%; */
border-radius: 4px; border-radius: 4px;
height: 5px;
transform: scaleX(0);
} }
@media (max-width: 480px) { @media (max-width: 480px) {
@ -205,6 +210,8 @@ video::-webkit-media-controls-enclosure {
background: transparent; background: transparent;
height: 4.5px; height: 4.5px;
cursor: pointer; cursor: pointer;
padding: 0;
outline: none;
} }
.progress input[type=range]:focus { .progress input[type=range]:focus {
@ -233,22 +240,6 @@ video::-webkit-media-controls-enclosure {
background: transparent; background: transparent;
} }
.progress input[type=range].volume {
height: 5px;
background-color: #fff;
}
.progress input[type=range].volume::-webkit-slider-runnable-track {
background-color: transparent;
}
.progress input[type=range].volume::-webkit-slider-thumb {
margin-left: 0;
height: 14px;
width: 14px;
background: #fff;
}
.progress input[type=range]::-moz-range-track { .progress input[type=range]::-moz-range-track {
width: 100%; width: 100%;
height: 8.4px; height: 8.4px;
@ -272,9 +263,22 @@ video::-webkit-media-controls-enclosure {
outline: none; outline: none;
} }
.progress input[type=range].volume::-moz-range-thumb { input[type=range]::-ms-track {
border: 1px solid #fff; visibility: hidden;
background: #fff; }
input[type=range]::-ms-ticks {
background: none;
color: none;
border: none;
}
input[type=range]::-ms-thumb {
visibility: hidden;
}
input[type=range]::-ms-tooltip {
visibility: hidden;
} }
.seek { .seek {
@ -294,9 +298,12 @@ video::-webkit-media-controls-enclosure {
align-items: center; align-items: center;
} }
.right-controls {
float: right;
}
.bottom-controls { .bottom-controls {
padding: 3px 4px 0px 4px; padding: 3px 4px 0px 4px;
//padding: 5px 4px 5px 4px;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
@ -327,8 +334,8 @@ video::-webkit-media-controls-enclosure {
align-items: center; align-items: center;
} }
video[data-ckin="circle"] { video[data-ckin="circle"] {
-webkit-clip-path: ellipse(100px 100px at center); border-radius: 50%;
clip-path: ellipse(100px 100px at center); overflow: hidden;
} }
.progress-ring { .progress-ring {
position: absolute; position: absolute;
@ -337,9 +344,7 @@ video[data-ckin="circle"] {
cursor: pointer; cursor: pointer;
} }
.progress-ring__circle { .progress-ring__circle {
transform-origin: center; transition: stroke-dashoffset;
transform: rotate(-90deg);
transition: stroke-dashoffset 0.15s;
} }
.ckin__player.circle { .ckin__player.circle {

25
src/scss/style.scss

@ -480,7 +480,8 @@ input {
position: relative; position: relative;
padding-left: 67px; padding-left: 67px;
min-height: 54px; min-height: 54px;
width: 256px; max-width: 286px;
overflow: visible!important;
&-toggle, &-download { &-toggle, &-download {
border-radius: 50%; border-radius: 50%;
@ -492,6 +493,28 @@ input {
&-download { &-download {
z-index: 2; z-index: 2;
} }
&-waveform {
height: 23px;
//overflow: visible!important;
rect {
//overflow: visible!important;
fill: #CBCBCB;
&.active {
fill: $blue;
}
}
}
&-time {
font-size: 14px;
color: $color-gray;
margin-top: 4px;
margin-left: -1px;
}
} }
.page-signUp { .page-signUp {

Loading…
Cancel
Save