From 956a260a27879be081a0235e78a14abb8150f81a Mon Sep 17 00:00:00 2001 From: Eduard Kuzmenko Date: Sat, 15 Feb 2020 23:47:14 +0700 Subject: [PATCH] audiomessages & new player --- src/components/wrappers.ts | 97 ++++- src/lib/appManagers/appSidebarRight.ts | 18 +- src/lib/ckin.js | 516 ++++++++++++++----------- src/scss/partials/_chat.scss | 26 ++ src/scss/partials/_ckin.scss | 109 +++--- src/scss/style.scss | 25 +- 6 files changed, 487 insertions(+), 304 deletions(-) diff --git a/src/components/wrappers.ts b/src/components/wrappers.ts index 29925c5f..87358c0e 100644 --- a/src/components/wrappers.ts +++ b/src/components/wrappers.ts @@ -29,7 +29,8 @@ export type MTDocument = { h?: number, w?: number, file_name?: string, - file?: File + file?: File, + duration?: number }; export type MTPhotoSize = { @@ -235,24 +236,56 @@ export function wrapDocument(doc: MTDocument, withTime = false): HTMLDivElement return docDiv; } +let lastAudioToggle: HTMLDivElement = null; + export function wrapAudio(doc: MTDocument, withTime = false): HTMLDivElement { let div = document.createElement('div'); div.classList.add('audio'); + let duration = doc.duration; + + // @ts-ignore + let durationStr = String(duration | 0).toHHMMSS(true); + div.innerHTML = `
-
-
-
+
${durationStr}
`; - 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 preloader: ProgressivePreloader; let promise: CancellablePromise; + 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', ` + + `); + + ++index; + } + let onClick = () => { if(!promise) { if(downloadDiv.classList.contains('downloading')) { @@ -276,9 +309,57 @@ export function wrapAudio(doc: MTDocument, withTime = false): HTMLDivElement { source.type = doc.mime_type; div.removeEventListener('click', onClick); - div.querySelector('.audio-toggle').addEventListener('click', () => { - audio.currentTime = 0; - audio.play(); + let toggle = div.querySelector('.audio-toggle') as HTMLDivElement; + + 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); diff --git a/src/lib/appManagers/appSidebarRight.ts b/src/lib/appManagers/appSidebarRight.ts index f07988f6..a937777a 100644 --- a/src/lib/appManagers/appSidebarRight.ts +++ b/src/lib/appManagers/appSidebarRight.ts @@ -112,7 +112,7 @@ class AppSidebarRight { this.prevTabID = id; - this.log('setVirtualContainer', id, this.sharedMediaSelected); + //this.log('setVirtualContainer', id, this.sharedMediaSelected); this.sidebarScroll.setVirtualContainer(this.sharedMediaSelected); if(this.savedVirtualStates[id]) { @@ -169,7 +169,7 @@ class AppSidebarRight { let media = Array.from(this.sharedMediaSelected.childNodes).slice(-15); for(let div of media) { if(isElementInViewport(div)) { - this.log('Will load more media'); + //this.log('Will load more media'); this.loadSidebarMedia(true); break; @@ -256,12 +256,12 @@ class AppSidebarRight { let media = message.media.photo || message.media.document || (message.media.webpage && message.media.webpage.document); if(!media) { - this.log('no media!', message); + //this.log('no media!', message); break; } if(media._ == 'document' && media.type != 'video'/* && media.type != 'gif' */) { - this.log('broken video', media); + //this.log('broken video', media); break; } @@ -334,7 +334,7 @@ class AppSidebarRight { let previewDiv = document.createElement('div'); previewDiv.classList.add('preview'); - this.log('wrapping webpage', webpage); + //this.log('wrapping webpage', webpage); if(webpage.photo) { let load = () => appPhotosManager.preloadPhoto(webpage.photo.id, appPhotosManager.choosePhotoSize(webpage.photo, 380, 0)) @@ -394,7 +394,7 @@ class AppSidebarRight { } */ default: - console.warn('death is my friend', message); + //console.warn('death is my friend', message); break; } }); @@ -416,7 +416,7 @@ class AppSidebarRight { this.loadSidebarMediaPromises = {}; this.lastSharedMediaDiv = document.createElement('div'); - this.log('fillProfileElements'); + //this.log('fillProfileElements'); this.savedVirtualStates = {}; this.prevTabID = -1; @@ -483,7 +483,7 @@ class AppSidebarRight { setText(userFull.rAbout, this.profileElements.bio); } - this.log('userFull', userFull); + //this.log('userFull', userFull); if(userFull.pinned_msg_id) { // request pinned message appImManager.pinnedMsgID = userFull.pinned_msg_id; @@ -499,7 +499,7 @@ class AppSidebarRight { return; } - this.log('chatInfo res 2:', chatFull); + //this.log('chatInfo res 2:', chatFull); if(chatFull.about) { setText(RichTextProcessor.wrapRichText(chatFull.about), this.profileElements.bio); diff --git a/src/lib/ckin.js b/src/lib/ckin.js index 070239c6..1951f551 100644 --- a/src/lib/ckin.js +++ b/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 hours = Math.floor(sec_num / 3600); let minutes = Math.floor((sec_num - (hours * 3600)) / 60); let seconds = sec_num - (hours * 3600) - (minutes * 60); 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; return minutes + ':' + seconds; } function stylePlayer(player, video) { - let skin = attachSkin(video.dataset.ckin); - player.classList.add(skin); - - let overlay = video.dataset.overlay; - addOverlay(player, overlay); - - let html = buildControls(skin); - player.insertAdjacentHTML('beforeend', html); + let skin = attachSkin(video.dataset.ckin); + player.classList.add(skin); - var stopAndScrubTimeout = 0; - - if(skin === 'default') { - var progress = player.querySelector('.progress');; - var progressBar = player.querySelector('.progress__filled'); - var toggle = player.querySelectorAll('.toggle'); - var fullScreenButton = player.querySelector('.fullscreen'); - var seek = player.querySelector('#seek'); - var timeElapsed = player.querySelector('#time-elapsed'); - var timeDuration = player.querySelector('#time-duration'); - seek.setAttribute('max', video.duration); - timeDuration.innerHTML = String(video.duration | 0).toHHMMSS(); - - toggle.forEach((button) => { - return button.addEventListener('click', () => { - togglePlay(video, player); - }); - }); - - video.addEventListener('click', function() { - togglePlay(this, player); - }); - - video.addEventListener('play', function() { - updateButton(this, toggle); - }); - - video.addEventListener('pause', function() { - updateButton(this, toggle); - }); - - let mousedown = false; - progress.addEventListener('mousemove', (e) => { - return mousedown && scrub(e, video, progress); - }); - progress.addEventListener('mousedown', (e) => { - //console.log(video.currentTime); - scrub(e, video, progress, progressBar); - //Таймер для того, чтобы стопать видео, если зажал мышку и не отпустил клик - stopAndScrubTimeout = setTimeout(function() { - togglePlay(video, player, 1); - }, 150); - - return mousedown = true; - }); - progress.addEventListener('mouseup', () => { - clearTimeout(stopAndScrubTimeout); - togglePlay(video, player, 0); - return mousedown = false; - }); - fullScreenButton.addEventListener('click', (e) => { - return toggleFullScreen(player, fullScreenButton); - }); - addListenerMulti(player, 'webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange', (e) => { - return onFullScreen(e, player); - }); - } - - if(skin === 'circle') { - let wrapper = document.createElement('div'); - wrapper.classList.add('circle-time-left'); - video.parentNode.insertBefore(wrapper, video); - wrapper.innerHTML = '
'; - - var circle = player.querySelector('.progress-ring__circle'); - var radius = circle.r.baseVal.value; - var circumference = 2 * Math.PI * radius; - 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'; - }); - - video.addEventListener('pause', () => { - iconVolume.style.display = ''; - }); - } - - //Для хрома - timeDuration.innerHTML = String(video.duration | 0).toHHMMSS(); - if(skin === 'default') seek.setAttribute('max', video.duration); - //Для Opera / Safari / IE - video.addEventListener('loadeddata', function() { - timeDuration.innerHTML = String(video.duration | 0).toHHMMSS(); - if(skin === 'default') seek.setAttribute('max', video.duration); - }) - - video.addEventListener('timeupdate', function() { - handleProgress(this, skin, timeDuration, circumference, circle, progressBar, seek, timeElapsed); - }); + let html = buildControls(skin); + player.insertAdjacentHTML('beforeend', html); + let updateInterval = 0; + let elapsed = 0; + let prevTime = 0; + + if (skin === 'default') { + var progress = player.querySelector('.progress');; + var progressBar = player.querySelector('.progress__filled'); + var toggle = player.querySelectorAll('.toggle'); + var fullScreenButton = player.querySelector('.fullscreen'); + var seek = player.querySelector('#seek'); + var timeElapsed = player.querySelector('#time-elapsed'); + var timeDuration = player.querySelector('#time-duration'); + timeDuration.innerHTML = String(video.duration | 0).toHHMMSS(); + + toggle.forEach((button) => { + return button.addEventListener('click', () => { + togglePlay(video, player); + }); + }); + + video.addEventListener('click', function () { + togglePlay(this, player); + }); + + video.addEventListener('play', function () { + updateButton(this, toggle); + updateInterval = setInterval(function () { + if (video.paused) return; //chtob ne prigal seek pri peremotke + //elapsed += 0.02; // Increase with timer interval + if (video.currentTime != prevTime) { + elapsed = video.currentTime; // Update if getCurrentTime was changed + prevTime = video.currentTime; + } + let scaleX = (elapsed / video.duration); + progressBar.style.transform = 'scaleX(' + scaleX + ')'; + if (video.paused) clearInterval(updateInterval); + seek.value = video.currentTime * 1000; + }, 20); + }); + + video.addEventListener('ended', function () { + progressBar.style.transform = 'scaleX(1)'; + seek.value = video.currentTime * 1000; + }); + + video.addEventListener('pause', function () { + updateButton(this, toggle); + clearInterval(updateInterval); + }); + + video.addEventListener('dblclick', function () { + return toggleFullScreen(player, fullScreenButton); + }) + + let mousedown = false; + let stopAndScrubTimeout = 0; + progress.addEventListener('mousemove', (e) => { + return mousedown && scrub(e, video, progress, progressBar); + }); + progress.addEventListener('mousedown', (e) => { + scrub(e, video, progress, progressBar, updateInterval); + //Таймер для того, чтобы стопать видео, если зажал мышку и не отпустил клик + stopAndScrubTimeout = setTimeout(function () { + togglePlay(video, player, 1); + }, 150); + + return mousedown = true; + }); + progress.addEventListener('mouseup', () => { + if (typeof stopAndScrubTimeout !== 'undefined') { + clearTimeout(stopAndScrubTimeout); + } + togglePlay(video, player, 0); + return mousedown = false; + }); + fullScreenButton.addEventListener('click', (e) => { + return toggleFullScreen(player, fullScreenButton); + }); + addListenerMulti(player, 'webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange', (e) => { + return onFullScreen(e, player); + }); + } + + if (skin === 'circle') { + let wrapper = document.createElement('div'); + wrapper.classList.add('circle-time-left'); + video.parentNode.insertBefore(wrapper, video); + wrapper.innerHTML = '
'; + + var circle = player.querySelector('.progress-ring__circle'); + var radius = circle.r.baseVal.value; + var circumference = 2 * Math.PI * radius; + 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) { - video.setAttribute("controls", "controls"); + video.setAttribute("controls", "controls"); } function togglePlay(video, player, stop) { - if(stop == 1) { - video['pause'](); - player.classList.remove('is-playing'); - return; - } else if(stop == 0) { - video['play'](); - player.classList.add('is-playing'); - return; - } - - let method = video.paused ? 'play' : 'pause'; - video[method](); - video.paused ? player.classList.remove('is-playing') : player.classList.add('is-playing'); + if (stop == 1) { + video['pause'](); + player.classList.remove('is-playing'); + return; + } else if (stop == 0) { + video['play'](); + player.classList.add('is-playing'); + return; + } + + let method = video.paused ? 'play' : 'pause'; + video[method](); + video.paused ? player.classList.remove('is-playing') : player.classList.add('is-playing'); } function updateButton(video, toggle) { - let icon = video.paused ? 'tgico-play' : 'tgico-pause'; - toggle.forEach((button) => { - button.classList.remove('tgico-play', 'tgico-pause'); - button.classList.add(icon); - }); + let icon = video.paused ? 'tgico-play' : 'tgico-pause'; + toggle.forEach((button) => { + button.classList.remove('tgico-play', 'tgico-pause'); + button.classList.add(icon); + }); } -function handleProgress(video, skin, timeDuration, circumference, circle, progressBar, seek, timeElapsed) { - let percent = video.currentTime / video.duration * 100; - if(skin === 'default') { - progressBar.style.width = percent + '%'; - seek.value = video.currentTime; - timeElapsed.innerHTML = String(video.currentTime | 0).toHHMMSS(); - } else if(skin === 'circle') { - let timeLeft = String((video.duration - video.currentTime) | 0).toHHMMSS(); - let offset = circumference - percent / 100 * circumference; - circle.style.strokeDashoffset = offset; - if(timeLeft != 0 | 0) timeDuration.innerHTML = timeLeft; - } +function handleProgress(video, skin, timeDuration, circumference, circle, progressBar, seek, timeElapsed, updateInterval, mousemove) { + clearInterval(updateInterval); + let elapsed = 0; + let prevTime = 0; + if (skin === 'default') { + updateInterval = setInterval(function () { + if (video.paused) return; + if (video.currentTime != prevTime) { + elapsed = video.currentTime; // Update if getCurrentTime was changed + prevTime = video.currentTime; + } + 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) { - let scrubTime = e.offsetX / progress.offsetWidth * video.duration; - video.currentTime = scrubTime; +function scrub(e, video, progress, progressBar) { + let scrubTime = e.offsetX / progress.offsetWidth * video.duration; + 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) { - let wrapper = document.createElement('div'); - wrapper.classList.add('ckin__player'); - - video.parentNode.insertBefore(wrapper, video); - wrapper.appendChild(video); + let wrapper = document.createElement('div'); + wrapper.classList.add('ckin__player'); + + video.parentNode.insertBefore(wrapper, video); + wrapper.appendChild(video); - stylePlayer(wrapper, video); + stylePlayer(wrapper, video); - return wrapper; + return wrapper; } function buildControls(skin) { - let html = []; - if(skin === 'default') { - html.push(''); - html.push('
'); - html.push('
', - '
', - '
', - '
', - '
', - '
', - '', - ' / ', - '', - '
', - '
', - '
'); - html.push('
'); - } else if(skin === 'circle') { - html.push('', - '', - ''); - } - - return html.join(''); -} + let html = []; + if (skin === 'default') { + html.push(''); + html.push('
'); + html.push('
'); + html.push('
', + '
', + '
', + '
', + '
', + '
', + '', + ' / ', + '', + '
', + '
', + '
'); + html.push('
'); + } else if (skin === 'circle') { + html.push('', + '', + ''); + } -function attachSkin(skin) { - console.log("skin: " + skin); - if(typeof skin != 'undefined' && skin != '') { - return skin; - } else { - return 'default'; - } + return html.join(''); } -function addOverlay(player, overlay) { - if(overlay == 1) { - player.classList.add('ckin__overlay'); - } else { - return; - } +function attachSkin(skin) { + console.log("skin: " + skin); + if (typeof skin != 'undefined' && skin != '') { + return skin; + } else { + return 'default'; + } } function toggleFullScreen(player, fullScreenButton) { - // alternative standard method - if(!document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) { - player.classList.add('ckin__fullscreen'); - - if(player.requestFullscreen) { - player.requestFullscreen(); - } else if(player.mozRequestFullScreen) { - player.mozRequestFullScreen(); // Firefox - } else if(player.webkitRequestFullscreen) { - player.webkitRequestFullscreen(); // Chrome and Safari - } else if(player.msRequestFullscreen) { - player.msRequestFullscreen(); - } - - fullScreenButton.classList.remove('tgico-fullscreen'); - fullScreenButton.classList.add('tgico-smallscreen'); - fullScreenButton.setAttribute('title', 'Exit Full Screen'); - } else { - player.classList.remove('ckin__fullscreen'); - - if(document.cancelFullScreen) { - document.cancelFullScreen(); - } else if(document.mozCancelFullScreen) { - document.mozCancelFullScreen(); - } else if(document.webkitCancelFullScreen) { - document.webkitCancelFullScreen(); - } else if(document.msExitFullscreen) { - document.msExitFullscreen(); - } - - fullScreenButton.classList.remove('tgico-smallscreen'); - fullScreenButton.classList.add('tgico-fullscreen'); - fullScreenButton.setAttribute('title', 'Full Screen'); - } + // alternative standard method + if (!document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) { + player.classList.add('ckin__fullscreen'); + + if (player.requestFullscreen) { + player.requestFullscreen(); + } else if (player.mozRequestFullScreen) { + player.mozRequestFullScreen(); // Firefox + } else if (player.webkitRequestFullscreen) { + player.webkitRequestFullscreen(); // Chrome and Safari + } else if (player.msRequestFullscreen) { + player.msRequestFullscreen(); + } + + fullScreenButton.classList.remove('tgico-fullscreen'); + fullScreenButton.classList.add('tgico-smallscreen'); + fullScreenButton.setAttribute('title', 'Exit Full Screen'); + } else { + player.classList.remove('ckin__fullscreen'); + + if (document.cancelFullScreen) { + document.cancelFullScreen(); + } else if (document.mozCancelFullScreen) { + document.mozCancelFullScreen(); + } else if (document.webkitCancelFullScreen) { + document.webkitCancelFullScreen(); + } else if (document.msExitFullscreen) { + document.msExitFullscreen(); + } + + fullScreenButton.classList.remove('tgico-smallscreen'); + fullScreenButton.classList.add('tgico-fullscreen'); + fullScreenButton.setAttribute('title', 'Full Screen'); + } } function onFullScreen(e, player) { - let isFullscreenNow = document.webkitFullscreenElement !== null; - if(!isFullscreenNow) { - player.classList.remove('ckin__fullscreen'); - - /* let el = player.querySelector('.fullscreen'); - el.classList.remove('tgico-smallscreen'); - el.classList.add('tgico-fullscreen'); */ - } else { - // player.querySelector('.fullscreen').innerHTML = iconExpand; - - } + let isFullscreenNow = document.webkitFullscreenElement !== null; + if (!isFullscreenNow) { + player.classList.remove('ckin__fullscreen'); + } else { + } } function addListenerMulti(element, eventNames, listener) { - let events = eventNames.split(' '); - for (let i = 0, iLen = events.length; i < iLen; i++) { - element.addEventListener(events[i], listener, false); - } + let events = eventNames.split(' '); + for (let i = 0, iLen = events.length; i < iLen; i++) { + element.addEventListener(events[i], listener, false); + } } diff --git a/src/scss/partials/_chat.scss b/src/scss/partials/_chat.scss index f7dd4d68..349dacc5 100644 --- a/src/scss/partials/_chat.scss +++ b/src/scss/partials/_chat.scss @@ -239,6 +239,12 @@ } } + &:not(.hide-name) { + .audio { + margin: 4px 0; + } + } + &:hover { .forward { opacity: 1; @@ -897,6 +903,26 @@ left: auto; right: -2.5rem; } + + .audio { + &-waveform { + rect { + fill: #B8DDA9; + + &.active { + fill: #68AB5A; + } + } + } + + &-time { + color: #68AB5A; + } + + &-toggle, &-download { + background-color: #68AB5A; + } + } } } diff --git a/src/scss/partials/_ckin.scss b/src/scss/partials/_ckin.scss index 8fcf33f7..b9549e9b 100644 --- a/src/scss/partials/_ckin.scss +++ b/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 { &__player { letter-spacing: 0.02em; @@ -65,7 +52,6 @@ left: 0; bottom: 0; right: 0; - //border-radius: 5px; transition: opacity .2s; opacity: 1; visibility: visible; @@ -87,7 +73,6 @@ color: #fff; outline: 0; padding: 3px 10px 6px 10px; - /* padding: 6px 10px 6px 10px; */ cursor: pointer; font-size: 24px; line-height: 1; @@ -134,16 +119,40 @@ right: 0; left: 0; transition: all .3s; - /* background: linear-gradient(to top, rgba(0, 0, 0, 0.65) 0%, transparent 100%); */ - /* font-size: 32px; */ text-align: left; direction: ltr; - /* padding-top: 7px; */ 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 { opacity: 0; visibility: hidden; @@ -168,9 +177,7 @@ .default .progress { position: relative; - display: -ms-flexbox; - display: flex; - margin: 0 8px; + margin: 0 16px; height: 5px; transition: height 0.3s; background: rgba(255, 255, 255, 0.38); @@ -180,13 +187,11 @@ } .default .progress__filled { - width: 0%; background: #63a2e3; - /* -ms-flex: 0; - flex: 0; - -ms-flex-preferred-size: 0%; - flex-basis: 0%; */ + transform-origin: left; border-radius: 4px; + height: 5px; + transform: scaleX(0); } @media (max-width: 480px) { @@ -205,6 +210,8 @@ video::-webkit-media-controls-enclosure { background: transparent; height: 4.5px; cursor: pointer; + padding: 0; + outline: none; } .progress input[type=range]:focus { @@ -233,22 +240,6 @@ video::-webkit-media-controls-enclosure { 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 { width: 100%; height: 8.4px; @@ -272,9 +263,22 @@ video::-webkit-media-controls-enclosure { outline: none; } -.progress input[type=range].volume::-moz-range-thumb { - border: 1px solid #fff; - background: #fff; +input[type=range]::-ms-track { + visibility: hidden; +} + +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 { @@ -294,9 +298,12 @@ video::-webkit-media-controls-enclosure { align-items: center; } +.right-controls { + float: right; +} + .bottom-controls { padding: 3px 4px 0px 4px; - //padding: 5px 4px 5px 4px; display: flex; justify-content: space-between; align-items: center; @@ -327,8 +334,8 @@ video::-webkit-media-controls-enclosure { align-items: center; } video[data-ckin="circle"] { - -webkit-clip-path: ellipse(100px 100px at center); - clip-path: ellipse(100px 100px at center); + border-radius: 50%; + overflow: hidden; } .progress-ring { position: absolute; @@ -337,9 +344,7 @@ video[data-ckin="circle"] { cursor: pointer; } .progress-ring__circle { - transform-origin: center; - transform: rotate(-90deg); - transition: stroke-dashoffset 0.15s; + transition: stroke-dashoffset; } .ckin__player.circle { diff --git a/src/scss/style.scss b/src/scss/style.scss index 84e36b47..919d79ed 100644 --- a/src/scss/style.scss +++ b/src/scss/style.scss @@ -480,7 +480,8 @@ input { position: relative; padding-left: 67px; min-height: 54px; - width: 256px; + max-width: 286px; + overflow: visible!important; &-toggle, &-download { border-radius: 50%; @@ -492,6 +493,28 @@ input { &-download { 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 {