Added new slider, implement audio player seek
This commit is contained in:
parent
1d26e46a5a
commit
0a74961cb8
137
app/css/app.css
137
app/css/app.css
@ -594,73 +594,31 @@ a.tg_radio_on:hover i.icon-radio {
|
|||||||
.tg_range_wrap {
|
.tg_range_wrap {
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
}
|
}
|
||||||
input.tg_range {
|
.tg_slider_wrap {
|
||||||
|
position: relative;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
outline: none !important;
|
line-height: 18px;
|
||||||
-webkit-appearance: none;
|
height: 18px;
|
||||||
width: 100%;
|
}
|
||||||
max-width: 362px;
|
.tg_slider_track {
|
||||||
display: inline-block;
|
position: absolute;
|
||||||
background: #c7c7c7;
|
background: #c7c7c7;
|
||||||
height: 3px;
|
height: 3px;
|
||||||
line-height: 18px;
|
|
||||||
vertical-align: top;
|
|
||||||
margin: 8px 0;
|
margin: 8px 0;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
|
||||||
input.tg_range::-moz-range-track {
|
|
||||||
cursor: pointer;
|
|
||||||
outline: none !important;
|
|
||||||
-webkit-appearance: none;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 362px;
|
z-index: 2;
|
||||||
display: inline-block;
|
|
||||||
background: #c7c7c7;
|
|
||||||
height: 3px;
|
|
||||||
line-height: 18px;
|
|
||||||
vertical-align: top;
|
|
||||||
margin: 8px 0;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
}
|
||||||
input.tg_range::-webkit-slider-thumb {
|
.tg_slider_thumb {
|
||||||
border: 0;
|
position: absolute;
|
||||||
-webkit-appearance: none;
|
|
||||||
background: #568cb5;
|
|
||||||
width: 12px;
|
|
||||||
height: 12px;
|
|
||||||
border-radius: 6px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
input.tg_range::-moz-range-thumb {
|
|
||||||
border: 0;
|
|
||||||
background: #568cb5;
|
|
||||||
width: 12px;
|
|
||||||
height: 12px;
|
|
||||||
border-radius: 6px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
input.tg_range::-ms-track {
|
|
||||||
color: transparent;
|
|
||||||
border: 0;
|
|
||||||
cursor: pointer;
|
|
||||||
outline: none !important;
|
|
||||||
width: 100%;
|
|
||||||
max-width: 362px;
|
|
||||||
display: inline-block;
|
|
||||||
background: #c7c7c7;
|
|
||||||
height: 3px;
|
|
||||||
line-height: 18px;
|
|
||||||
vertical-align: top;
|
|
||||||
margin: 8px 0;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
input.tg_range::-ms-thumb {
|
|
||||||
border: 0;
|
border: 0;
|
||||||
background: #568cb5;
|
background: #568cb5;
|
||||||
width: 12px;
|
width: 12px;
|
||||||
height: 12px;
|
height: 12px;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
|
margin-top: 4px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
z-index: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1506,8 +1464,8 @@ img.im_message_document_thumb {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
padding: 0 0 1px;
|
padding: 1px 0 1px;
|
||||||
line-height: 18px;
|
line-height: 16px;
|
||||||
height: 19px;
|
height: 19px;
|
||||||
}
|
}
|
||||||
.audio_player_title {
|
.audio_player_title {
|
||||||
@ -1529,6 +1487,64 @@ img.im_message_document_thumb {
|
|||||||
color: #999;
|
color: #999;
|
||||||
padding-left: 2px;
|
padding-left: 2px;
|
||||||
}
|
}
|
||||||
|
.audio_player_seek_slider {
|
||||||
|
float: left;
|
||||||
|
margin-right: 17px;
|
||||||
|
width: 236px;
|
||||||
|
}
|
||||||
|
.audio_player_seek_slider .tg_slider_wrap {
|
||||||
|
height: 16px;
|
||||||
|
line-height: 16px;
|
||||||
|
}
|
||||||
|
.audio_player_seek_slider .tg_slider_thumb {
|
||||||
|
background: #6490b1;
|
||||||
|
width: 4px;
|
||||||
|
height: 16px;
|
||||||
|
line-height: 16px;
|
||||||
|
margin-top: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
.audio_player_seek_slider .tg_slider_track {
|
||||||
|
margin: 6px 0;
|
||||||
|
background: rgba(218,228,234,0.50);
|
||||||
|
height: 4px;
|
||||||
|
}
|
||||||
|
.audio_player_seek_slider .tg_slider_track_fill {
|
||||||
|
background: #6490b1;
|
||||||
|
height: 4px;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio_player_volume_slider {
|
||||||
|
width: 50px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.audio_player_volume_slider .tg_slider_wrap {
|
||||||
|
height: 16px;
|
||||||
|
line-height: 16px;
|
||||||
|
}
|
||||||
|
.audio_player_volume_slider .tg_slider_thumb {
|
||||||
|
display: none;
|
||||||
|
background: #6490b1;
|
||||||
|
width: 4px;
|
||||||
|
height: 8px;
|
||||||
|
line-height: 16px;
|
||||||
|
margin-top: 4px;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
.audio_player_volume_slider:hover .tg_slider_thumb {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.audio_player_volume_slider .tg_slider_track {
|
||||||
|
margin: 6px 0;
|
||||||
|
background: rgba(218,228,234,0.50);
|
||||||
|
height: 4px;
|
||||||
|
}
|
||||||
|
.audio_player_volume_slider .tg_slider_track_fill {
|
||||||
|
background: #6490b1;
|
||||||
|
height: 4px;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.im_message_upload_progress_wrap,
|
.im_message_upload_progress_wrap,
|
||||||
.im_message_download_progress_wrap {
|
.im_message_download_progress_wrap {
|
||||||
@ -1536,11 +1552,14 @@ img.im_message_document_thumb {
|
|||||||
width: 290px;
|
width: 290px;
|
||||||
}
|
}
|
||||||
.audio_player_progress_wrap {
|
.audio_player_progress_wrap {
|
||||||
margin-top: 5px;
|
margin-top: 4px;
|
||||||
max-width: 290px;
|
/*max-width: 290px;*/
|
||||||
border-radius: 2px;
|
width: 303px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
.audio_player_progress_wrap .tg_down_progress {
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.im_message_document_thumbed .im_message_document_name_wrap,
|
.im_message_document_thumbed .im_message_document_name_wrap,
|
||||||
.im_message_document_thumbed .im_message_upload_progress_wrap,
|
.im_message_document_thumbed .im_message_upload_progress_wrap,
|
||||||
|
@ -792,6 +792,12 @@ div.im_panel_own_photo {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.settings_volume_slider {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 362px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.im_message_selected .im_message_outer_wrap,
|
.im_message_selected .im_message_outer_wrap,
|
||||||
.im_message_focus .im_message_outer_wrap {
|
.im_message_focus .im_message_outer_wrap {
|
||||||
|
@ -2046,5 +2046,88 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.seek = function (position) {
|
||||||
|
$scope.mediaPlayer.player.seek(position);
|
||||||
|
};
|
||||||
|
$scope.setVolume = function (volume) {
|
||||||
|
$scope.mediaPlayer.player.setVolume(volume);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
.directive('mySlider', function ($window) {
|
||||||
|
return {
|
||||||
|
link: link,
|
||||||
|
templateUrl: templateUrl('slider')
|
||||||
|
};
|
||||||
|
|
||||||
|
function link ($scope, element, attrs) {
|
||||||
|
var wrap = $('.tg_slider_wrap', element);
|
||||||
|
var fill = $('.tg_slider_track_fill', element);
|
||||||
|
var thumb = $('.tg_slider_thumb', element);
|
||||||
|
var width = wrap.width();
|
||||||
|
var thumbWidth = Math.ceil(thumb.width());
|
||||||
|
var model = attrs.sliderModel;
|
||||||
|
var sliderCallback = attrs.sliderOnchange;
|
||||||
|
var minValue = $scope.$eval(attrs.sliderMin) || 0.0;
|
||||||
|
var maxValue = $scope.$eval(attrs.sliderMax) || 1.0;
|
||||||
|
var lastUpdValue = false;
|
||||||
|
var lastMinPageX = false;
|
||||||
|
|
||||||
|
var onMouseMove = function (e) {
|
||||||
|
var offsetX = e.pageX - lastMinPageX;
|
||||||
|
offsetX = Math.min(width, Math.max(0 , offsetX));
|
||||||
|
// console.log('mmove', lastMinPageX, e.pageX, offsetX);
|
||||||
|
lastUpdValue = minValue + offsetX / width * (maxValue - minValue);
|
||||||
|
if (sliderCallback) {
|
||||||
|
$scope.$eval(sliderCallback, {value: lastUpdValue});
|
||||||
|
} else {
|
||||||
|
$scope.$eval(model + '=' + lastUpdValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
thumb.css('left', Math.max(0, offsetX - thumbWidth));
|
||||||
|
fill.css('width', offsetX);
|
||||||
|
|
||||||
|
return cancelEvent(e);
|
||||||
|
};
|
||||||
|
var stopMouseTrack = function () {
|
||||||
|
$($window).off('mousemove', onMouseMove);
|
||||||
|
$($window).off('mouseup', stopMouseTrack);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.$watch(model, function (newVal) {
|
||||||
|
if (newVal != lastUpdValue) {
|
||||||
|
var offsetX = width * (newVal - minValue) / (maxValue - minValue);
|
||||||
|
offsetX = Math.min(width, Math.max(0 , offsetX));
|
||||||
|
thumb.css('left', Math.max(0, offsetX - thumbWidth));
|
||||||
|
fill.css('width', offsetX);
|
||||||
|
lastUpdValue = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
element.on('dragstart selectstart', cancelEvent);
|
||||||
|
|
||||||
|
element.on('mousedown', function (e) {
|
||||||
|
stopMouseTrack();
|
||||||
|
|
||||||
|
lastMinPageX = e.pageX - e.offsetX;
|
||||||
|
// console.log('mdown', lastMinPageX, e.pageX, e.offsetX);
|
||||||
|
lastUpdValue = minValue + e.offsetX / width * (maxValue - minValue);
|
||||||
|
if (sliderCallback) {
|
||||||
|
$scope.$eval(sliderCallback, {value: lastUpdValue});
|
||||||
|
} else {
|
||||||
|
$scope.$eval(model + '=' + lastUpdValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
thumb.css('left', e.offsetX);
|
||||||
|
fill.css('width', e.offsetX);
|
||||||
|
|
||||||
|
$($window).on('mousemove', onMouseMove);
|
||||||
|
$($window).on('mouseup', stopMouseTrack);
|
||||||
|
|
||||||
|
return cancelEvent(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
@ -21,8 +21,9 @@
|
|||||||
<div ng-switch-when="true" class="progress tg_down_progress">
|
<div ng-switch-when="true" class="progress tg_down_progress">
|
||||||
<div class="progress-bar progress-bar-success" ng-style="{width: audio.progress.percent + '%'}"></div>
|
<div class="progress-bar progress-bar-success" ng-style="{width: audio.progress.percent + '%'}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div ng-switch-default class="progress tg_play_progress">
|
<div ng-switch-default>
|
||||||
<div class="progress-bar progress-bar-success" ng-style="{width: mediaPlayer.player.currentTime / (mediaPlayer.player.duration || audio.duration) * 100 + '%'}"></div>
|
<div class="audio_player_seek_slider" my-slider slider-model="mediaPlayer.player.currentTime" slider-min="0" slider-max="mediaPlayer.player.duration || audio.duration" slider-onchange="seek(value)"></div>
|
||||||
|
<div class="audio_player_volume_slider" my-slider slider-model="mediaPlayer.player.volume" slider-min="0" slider-max="1" slider-onchange="setVolume(value)"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<audio ng-if="audio.url" media-player="mediaPlayer.player">
|
<audio ng-if="audio.url" media-player="mediaPlayer.player">
|
||||||
|
@ -97,7 +97,7 @@
|
|||||||
<i class="icon-volume-inner icon-volume-inner3"></i>
|
<i class="icon-volume-inner icon-volume-inner3"></i>
|
||||||
<i class="icon-volume-inner icon-volume-inner4"></i>
|
<i class="icon-volume-inner icon-volume-inner4"></i>
|
||||||
</span>
|
</span>
|
||||||
<input type="range" class="tg_range" ng-model="notify.volume" min="1" max="10">
|
<div class="settings_volume_slider" my-slider slider-model="notify.volume" slider-min="1" slider-max="10"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
6
app/partials/desktop/slider.html
Normal file
6
app/partials/desktop/slider.html
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<div class="tg_slider_wrap">
|
||||||
|
<div class="tg_slider_thumb"></div>
|
||||||
|
<div class="tg_slider_track">
|
||||||
|
<div class="tg_slider_track_fill"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
Loading…
Reference in New Issue
Block a user