Browse Source

Improved attachments rendering

master
Igor Zhukov 10 years ago
parent
commit
96db3f036a
  1. 142
      app/css/app.css
  2. 8
      app/css/mobile.css
  3. 21
      app/js/controllers.js
  4. 140
      app/js/directives.js
  5. 29
      app/js/filters.js
  6. 1
      app/js/locales/en-us.json
  7. 182
      app/js/services.js
  8. 36
      app/partials/desktop/audio_player.html
  9. 4
      app/partials/desktop/full_gif.html
  10. 14
      app/partials/desktop/full_video.html
  11. 2
      app/partials/desktop/message.html
  12. 2
      app/partials/desktop/message_attach_document.html
  13. 8
      app/partials/desktop/message_attach_pending.html
  14. 25
      app/partials/desktop/message_attach_video.html
  15. 2
      app/partials/desktop/settings_modal.html
  16. 6
      app/partials/mobile/full_gif.html
  17. 14
      app/partials/mobile/full_video.html
  18. 2
      app/partials/mobile/message.html
  19. 37
      app/partials/mobile/message_attach_document.html
  20. 2
      app/partials/mobile/message_attach_pending.html
  21. 6
      app/partials/mobile/message_attach_video.html
  22. 2
      app/partials/mobile/photo_modal.html
  23. 1
      app/partials/mobile/slider.html
  24. 2
      app/partials/mobile/video_modal.html

142
app/css/app.css

@ -1328,12 +1328,12 @@ div.im_message_video_thumb { @@ -1328,12 +1328,12 @@ div.im_message_video_thumb {
z-index: 1;
}
.im_message_video,
.im_message_document,
.im_message_upload_file {
.im_message_upload_file,
.im_message_audio {
margin-top: 3px;
/*border-radius: 3px;*/
/*display: inline-block;*/
width: 342px;
width: 317px;
}
.im_message_audio {
margin-top: 3px;
@ -1366,6 +1366,29 @@ div.im_message_video_thumb { @@ -1366,6 +1366,29 @@ div.im_message_video_thumb {
height: 18px;
margin: 12px 13px;
}
.im_message_file_button_dl_audio {
background: #6490b1;
border-radius: 2px;
}
.im_message_file_button_dl_audio .im_message_file_button_icon {
display: block;
width: 15px;
height: 18px;
background: url(../img/icons/IconsetW.png) -15px -897px no-repeat;
background-size: 42px 1171px;
margin: 12px 13.5px;
}
.is_1x .im_message_file_button_dl_audio .im_message_file_button_icon {
background-image: url(../img/icons/IconsetW_1x.png);
background-position: -15px -899px;
}
.im_message_file_button_dl_audio .audio_player_btn_icon_pause,
.is_1x .im_message_file_button_dl_audio .audio_player_btn_icon_pause {
width: 12px;
height: 16px;
background-position: -15px -927px;
margin: 13px 15px;
}
.im_message_selected .icon-document,
.im_history_selectable .im_message_outer_wrap:hover .icon-document {
@ -1403,11 +1426,11 @@ img.im_message_document_thumb { @@ -1403,11 +1426,11 @@ img.im_message_document_thumb {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
width: 290px;
width: 265px;
padding: 0 0 1px;
}
.im_message_document_actions {
width: 290px;
width: 265px;
}
@ -1415,7 +1438,7 @@ img.im_message_document_thumb { @@ -1415,7 +1438,7 @@ img.im_message_document_thumb {
color: #3a6d99;
display: inline-block;
font-weight: bold;
max-width: 200px;
max-width: 170px;
overflow: hidden;
vertical-align: text-top;
white-space: nowrap;
@ -1424,42 +1447,12 @@ img.im_message_document_thumb { @@ -1424,42 +1447,12 @@ img.im_message_document_thumb {
.im_message_document_size {
color: #999;
padding-left: 2px;
vertical-align: text-top;
}
.im_message_document_actions a,
.audio_player_actions a {
margin-right: 10px;
}
.audio_player_button {
width: 42px;
height: 42px;
padding-left: 14px;
padding-right: 14px;
border-radius: 2px;
margin-right: 12px;
}
.audio_player_btn_icon {
display: block;
width: 14px;
height: 17px;
background: url(../img/icons/IconsetW.png) -15px -897px no-repeat;
background-size: 42px 1171px;
}
.is_1x .audio_player_btn_icon {
background-image: url(../img/icons/IconsetW_1x.png);
background-position: -15px -898px;
}
.audio_player_btn_icon_pause,
.is_1x .audio_player_btn_icon_pause,
.audio_player_btn_icon_cancel,
.is_1x .audio_player_btn_icon_cancel {
width: 13px;
height: 15px;
background-position: -15px -923px;
}
.is_1x .audio_player_btn_icon_pause,
.is_1x .audio_player_btn_icon_cancel {
background-position: -15px -925px;
}
.audio_player_title_wrap {
overflow: hidden;
white-space: nowrap;
@ -1467,11 +1460,12 @@ img.im_message_document_thumb { @@ -1467,11 +1460,12 @@ img.im_message_document_thumb {
padding: 1px 0 1px;
line-height: 16px;
height: 19px;
width: 200px;
}
.audio_player_title {
display: inline-block;
font-weight: bold;
max-width: 200px;
max-width: 85px;
overflow: hidden;
vertical-align: text-top;
white-space: nowrap;
@ -1487,10 +1481,14 @@ img.im_message_document_thumb { @@ -1487,10 +1481,14 @@ img.im_message_document_thumb {
color: #999;
padding-left: 2px;
}
.audio_player_actions {
margin-top: 3px;
}
.audio_player_seek_slider {
float: left;
margin-right: 17px;
width: 236px;
margin-right: 15px;
width: 200px;
}
.audio_player_seek_slider .tg_slider_wrap {
height: 16px;
@ -1508,6 +1506,7 @@ img.im_message_document_thumb { @@ -1508,6 +1506,7 @@ img.im_message_document_thumb {
margin: 6px 0;
background: rgba(218,228,234,0.50);
height: 4px;
border-radius: 0;
}
.audio_player_seek_slider .tg_slider_track_fill {
background: #6490b1;
@ -1546,49 +1545,56 @@ img.im_message_document_thumb { @@ -1546,49 +1545,56 @@ img.im_message_document_thumb {
width: 0;
}
.im_message_upload_progress_wrap,
.im_message_download_progress_wrap {
margin-top: 5px;
width: 290px;
}
.audio_player_progress_wrap {
margin-top: 4px;
/*max-width: 290px;*/
width: 303px;
overflow: hidden;
}
.audio_player_progress_wrap .tg_down_progress {
margin-top: 5px;
}
.im_message_upload_progress_wrap,
.im_message_download_progress_wrap {
margin-top: 5px;
width: 200px;
}
.im_message_document_thumbed .im_message_document_name_wrap,
.im_message_document_thumbed .im_message_upload_progress_wrap,
.im_message_document_thumbed .im_message_download_progress_wrap,
.im_message_document_thumbed .im_message_document_actions {
width: 230px;
width: 207px;
}
.im_message_document_thumbed .im_message_document_name {
max-width: 150px;
max-width: 110px;
}
.im_message_video .im_message_document_name_wrap,
.im_message_video .im_message_download_progress_wrap,
.im_message_video .im_message_document_actions {
width: 150px;
width: 152px;
}
.im_message_video .im_message_document_name_wrap {
margin-top: 5px;
}
.im_message_cancelable_progress_wrap,
.im_message_playback_progress_wrap {
margin-top: 4px;
/*width: 265px;*/
}
.im_message_media_progress_cancel {
font-size: 11px;
margin-left: 10px;
margin-left: 15px;
line-height: 100%;
width: 50px;
display: block;
overflow: hidden;
}
.tg_up_progress,
.tg_down_progress,
.tg_play_progress {
height: 5px;
.tg_down_progress {
height: 4px;
margin: 0;
padding: 0;
background: rgba(218,228,234,0.50);
@ -1598,26 +1604,15 @@ img.im_message_document_thumb { @@ -1598,26 +1604,15 @@ img.im_message_document_thumb {
box-shadow: none;
}
.tg_up_progress .progress-bar,
.tg_down_progress .progress-bar,
.tg_play_progress .progress-bar {
height: 5px;
line-height: 5px;
.tg_down_progress .progress-bar {
height: 4px;
line-height: 4px;
background: #6B9ABD;
border-radius: 0;
overflow: hidden;
-webkit-box-shadow: none;
box-shadow: none;
}
.tg_play_progress {
background: rgba(218,228,234,0.50);
border-radius: 1px;
}
.tg_play_progress .progress-bar {
background: #628fb2;
border-radius: 1px;
-webkit-transition: none;
transition: none;
}
@ -2757,4 +2752,9 @@ ce671b orange @@ -2757,4 +2752,9 @@ ce671b orange
font-size: 14px;
line-height: 160%;
margin: 25px 0 30px;
}
#nacl_listener {
position: absolute;
left: -10000px;
}

8
app/css/mobile.css

@ -130,7 +130,7 @@ html { @@ -130,7 +130,7 @@ html {
vertical-align: text-top;
background: url(../img/icons/IconsetW.png) -15px -835px no-repeat;
background-size: 42px 971px;
background-size: 42px 1171px;
opacity: 0.8;
}
.is_1x .icon-back {
@ -959,7 +959,7 @@ a.mobile_modal_action .tg_checkbox_label { @@ -959,7 +959,7 @@ a.mobile_modal_action .tg_checkbox_label {
.im_submit:active,
.im_submit:hover {
background: url(../img/icons/IconsetW.png) 2px -860px no-repeat;
background-size: 42px 971px;
background-size: 42px 1171px;
color: transparent;
box-shadow: none;
}
@ -983,7 +983,7 @@ a.mobile_modal_action .tg_checkbox_label { @@ -983,7 +983,7 @@ a.mobile_modal_action .tg_checkbox_label {
height: 23px;
vertical-align: text-top;
background: url(../img/icons/IconsetW.png) -12px -68px no-repeat;
background-size: 42px 971px;
background-size: 42px 1171px;
opacity: 0.8;
}
.is_1x .icon-paperclip {
@ -1020,7 +1020,7 @@ a.mobile_modal_action .tg_checkbox_label { @@ -1020,7 +1020,7 @@ a.mobile_modal_action .tg_checkbox_label {
opacity: 1;
margin: 0;
background: url(../img/icons/IconsetW.png) -10px -771px no-repeat;
background-size: 42px 971px;
background-size: 42px 1171px;
}
.is_1x .icon-emoji {
background-image: url(../img/icons/IconsetW_1x.png);

21
app/js/controllers.js

@ -316,7 +316,7 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -316,7 +316,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
ChangelogNotifyService.checkUpdate();
})
.controller('AppIMController', function ($scope, $location, $routeParams, $modal, $rootScope, $modalStack, MtpApiManager, AppUsersManager, ContactsSelectService, ChangelogNotifyService, ErrorService, AppRuntimeManager) {
.controller('AppIMController', function ($scope, $location, $routeParams, $modal, $rootScope, $modalStack, MtpApiManager, AppUsersManager, AppChatsManager, ContactsSelectService, ChangelogNotifyService, ErrorService, AppRuntimeManager) {
$scope.$on('$routeUpdate', updateCurDialog);
@ -400,9 +400,9 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -400,9 +400,9 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.showPeerInfo = function () {
if ($scope.curDialog.peerID > 0) {
$rootScope.openUser($scope.curDialog.peerID)
AppUsersManager.openUser($scope.curDialog.peerID)
} else if ($scope.curDialog.peerID < 0) {
$rootScope.openChat(-$scope.curDialog.peerID)
AppChatsManager.openChat(-$scope.curDialog.peerID)
}
};
@ -2120,7 +2120,7 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -2120,7 +2120,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
}
});
$scope.notify = {};
$scope.notify = {volume: 0.5};
$scope.send = {};
$scope.$watch('photo.file', onPhotoSelected);
@ -2210,31 +2210,30 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -2210,31 +2210,30 @@ angular.module('myApp.controllers', ['myApp.i18n'])
if (settings[1]) {
$scope.notify.volume = 0;
} else if (settings[3] !== false) {
$scope.notify.volume = settings[3] > 0 && Math.ceil(settings[3] * 10) || 0;
$scope.notify.volume = settings[3] > 0 && settings[3] <= 1.0 ? settings[3] : 0;
} else {
$scope.notify.volume = 5;
$scope.notify.volume = 0.5;
}
$scope.notify.canVibrate = NotificationsManager.getVibrateSupport();
$scope.notify.vibrate = !settings[4];
$scope.notify.volumeOf4 = function () {
return 1 + Math.ceil(($scope.notify.volume - 1) / 3.3);
return 1 + Math.ceil(($scope.notify.volume - 0.1) / 0.33);
};
$scope.toggleSound = function () {
if ($scope.notify.volume) {
$scope.notify.volume = 0;
} else {
$scope.notify.volume = 5;
$scope.notify.volume = 0.5;
}
}
var testSoundPromise;
$scope.$watch('notify.volume', function (newValue, oldValue) {
if (newValue !== oldValue) {
var storeVolume = newValue / 10;
Storage.set({notify_volume: storeVolume});
Storage.set({notify_volume: newValue});
Storage.remove('notify_nosound');
NotificationsManager.clear();
@ -2242,7 +2241,7 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -2242,7 +2241,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$timeout.cancel(testSoundPromise);
}
testSoundPromise = $timeout(function () {
NotificationsManager.testSound(storeVolume);
NotificationsManager.testSound(newValue);
}, 500);
}
});

140
app/js/directives.js

@ -177,9 +177,22 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -177,9 +177,22 @@ angular.module('myApp.directives', ['myApp.filters'])
templateUrl: templateUrl('message_attach_photo')
};
})
.directive('myMessageVideo', function() {
.directive('myMessageVideo', function(AppVideoManager) {
return {
templateUrl: templateUrl('message_attach_video')
scope: {
'video': '=myMessageVideo',
'messageId': '=messageId'
},
templateUrl: templateUrl('message_attach_video'),
link: function ($scope, element, attrs) {
AppVideoManager.updateVideoDownloaded($scope.video.id);
$scope.videoSave = function () {
AppVideoManager.saveVideoFile($scope.video.id);
};
$scope.videoOpen = function () {
AppVideoManager.openVideo($scope.video.id, $scope.messageId);
};
}
};
})
.directive('myMessageDocument', function(AppDocsManager) {
@ -1338,7 +1351,7 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -1338,7 +1351,7 @@ angular.module('myApp.directives', ['myApp.filters'])
})
.directive('myLoadVideo', function($sce, MtpApiFileManager, _) {
.directive('myLoadVideo', function($sce, AppVideoManager, _) {
return {
link: link,
@ -1351,37 +1364,12 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -1351,37 +1364,12 @@ angular.module('myApp.directives', ['myApp.filters'])
function link ($scope, element, attrs) {
$scope.progress = {enabled: true, percent: 1};
$scope.player = {};
var downloadPromise = AppVideoManager.downloadVideo($scope.video.id);
var inputLocation = {
_: 'inputVideoFileLocation',
id: $scope.video.id,
access_hash: $scope.video.access_hash
};
var hasQt = false, i;
if (navigator.plugins) {
for (i = 0; i < navigator.plugins.length; i++) {
if (navigator.plugins[i].name.indexOf('QuickTime') >= 0) {
hasQt = true;
}
}
}
var downloadPromise = MtpApiFileManager.downloadFile($scope.video.dc_id, inputLocation, $scope.video.size, {mime: 'video/mp4'});
downloadPromise.then(function (url) {
$scope.progress.enabled = false;
// $scope.progress = {enabled: true, percent: 50};
$scope.player.hasQuicktime = hasQt;
$scope.player.quicktime = false;
$scope.player.src = $sce.trustAsResourceUrl(url);
downloadPromise.then(function () {
$scope.$emit('ui_height');
}, function (e) {
console.log('Download video failed', e, $scope.video);
$scope.progress.enabled = false;
$scope.player.src = '';
if (e && e.type == 'FS_BROWSER_UNSUPPORTED') {
$scope.error = {html: _('error_browser_no_local_file_system_video_md', {
@ -1393,8 +1381,6 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -1393,8 +1381,6 @@ angular.module('myApp.directives', ['myApp.filters'])
$scope.error = {text: _('error_video_download_failed'), error: e};
}
}, function (progress) {
$scope.progress.percent = Math.max(1, Math.floor(100 * progress.done / progress.total));
});
$scope.$emit('ui_height');
@ -1406,7 +1392,7 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -1406,7 +1392,7 @@ angular.module('myApp.directives', ['myApp.filters'])
})
.directive('myLoadGif', function($rootScope, MtpApiFileManager, AppDocsManager) {
.directive('myLoadGif', function(AppDocsManager) {
return {
link: link,
@ -1418,15 +1404,9 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -1418,15 +1404,9 @@ angular.module('myApp.directives', ['myApp.filters'])
function link ($scope, element, attrs) {
var downloadPromise = false,
inputFileLocation = {
_: 'inputDocumentFileLocation',
id: $scope.document.id,
access_hash: $scope.document.access_hash
};
var downloadPromise = false;
$scope.isActive = false;
$scope.document.url = MtpApiFileManager.getCachedFile(inputFileLocation);
$scope.toggle = function (e) {
if (checkClick(e, true)) {
@ -1446,34 +1426,17 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -1446,34 +1426,17 @@ angular.module('myApp.directives', ['myApp.filters'])
return;
}
$scope.document.progress = {enabled: true, percent: 1, total: $scope.document.size};
downloadPromise = AppDocsManager.downloadDoc($scope.document.id);
downloadPromise = MtpApiFileManager.downloadFile(
$scope.document.dc_id,
inputFileLocation,
$scope.document.size,
null,
{mime: $scope.document.mime_type}
);
downloadPromise.then(function (url) {
$scope.document.url = url;
downloadPromise.then(function () {
$scope.isActive = true;
delete $scope.document.progress;
console.log('file save done');
$scope.$emit('ui_height');
}, function () {
$scope.document.progress.enabled = false;
}, function (progress) {
console.log('dl progress', progress);
$scope.document.progress.done = progress.done;
$scope.document.progress.percent = Math.max(1, Math.floor(100 * progress.done / progress.total));
})
}
}
})
.directive('myLoadDocument', function($rootScope, MtpApiFileManager, AppDocsManager) {
.directive('myLoadDocument', function(MtpApiFileManager, AppDocsManager) {
return {
link: link,
@ -1869,7 +1832,7 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -1869,7 +1832,7 @@ angular.module('myApp.directives', ['myApp.filters'])
})
.directive('myUserLink', function ($timeout, $rootScope, AppUsersManager) {
.directive('myUserLink', function ($timeout, AppUsersManager) {
return {
link: link
@ -1885,7 +1848,7 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -1885,7 +1848,7 @@ angular.module('myApp.directives', ['myApp.filters'])
if (element[0].tagName == 'A') {
element.on('click', function () {
$rootScope.openUser(userID, attrs.userOverride && $scope.$eval(attrs.userOverride));
AppUsersManager.openUser(userID, attrs.userOverride && $scope.$eval(attrs.userOverride));
});
}
if (attrs.color && $scope.$eval(attrs.color)) {
@ -1939,7 +1902,7 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -1939,7 +1902,7 @@ angular.module('myApp.directives', ['myApp.filters'])
})
.directive('myUserPhotolink', function ($rootScope, AppUsersManager) {
.directive('myUserPhotolink', function (AppUsersManager) {
return {
link: link,
@ -1958,7 +1921,7 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -1958,7 +1921,7 @@ angular.module('myApp.directives', ['myApp.filters'])
if (element[0].tagName == 'A') {
element.on('click', function (e) {
$rootScope.openUser($scope.userID, attrs.userOverride && $scope.$eval(attrs.userOverride));
AppUsersManager.openUser($scope.userID, attrs.userOverride && $scope.$eval(attrs.userOverride));
});
}
@ -1969,9 +1932,16 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -1969,9 +1932,16 @@ angular.module('myApp.directives', ['myApp.filters'])
}
})
.directive('myAudioPlayer', function ($sce, $timeout, $q, FileManager, MtpApiFileManager) {
.directive('myAudioPlayer', function ($timeout, $q, Storage, AppAudioManager, AppDocsManager) {
var currentPlayer = false;
var audioVolume = 0.5;
Storage.get('audio_volume').then(function (newAudioVolume) {
if (newAudioVolume >= 0.0 && newAudioVolume <= 1.0) {
audioVolume = newAudioVolume;
}
});
return {
link: link,
@ -2014,12 +1984,12 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -2014,12 +1984,12 @@ angular.module('myApp.directives', ['myApp.filters'])
$scope.mediaPlayer.player.playPause();
}
else if ($scope.audio.progress && $scope.audio.progress.enabled) {
$scope.audio.progress.cancel();
return;
}
else {
var downloadPromise;
if ($scope.audio._ == 'audio') {
downloadPromise = AppAudioManager.downloadDoc($scope.audio.id);
downloadPromise = AppAudioManager.downloadAudio($scope.audio.id);
} else {
downloadPromise = AppDocsManager.downloadDoc($scope.audio.id);
}
@ -2027,6 +1997,7 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -2027,6 +1997,7 @@ angular.module('myApp.directives', ['myApp.filters'])
downloadPromise.then(function () {
onContentLoaded(function () {
checkPlayer($scope.mediaPlayer.player);
$scope.mediaPlayer.player.setVolume(audioVolume);
$scope.mediaPlayer.player.play();
})
})
@ -2034,10 +2005,18 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -2034,10 +2005,18 @@ angular.module('myApp.directives', ['myApp.filters'])
};
$scope.seek = function (position) {
$scope.mediaPlayer.player.seek(position);
if ($scope.mediaPlayer && $scope.mediaPlayer.player) {
$scope.mediaPlayer.player.seek(position);
} else {
$scope.togglePlay();
}
};
$scope.setVolume = function (volume) {
$scope.mediaPlayer.player.setVolume(volume);
audioVolume = volume;
Storage.set({audio_volume: volume});
if ($scope.mediaPlayer && $scope.mediaPlayer.player) {
$scope.mediaPlayer.player.setVolume(volume);
}
};
}
})
@ -2060,7 +2039,7 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -2060,7 +2039,7 @@ angular.module('myApp.directives', ['myApp.filters'])
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));
@ -2084,10 +2063,16 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -2084,10 +2063,16 @@ angular.module('myApp.directives', ['myApp.filters'])
$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);
var percent = Math.max(0, (newVal - minValue) / (maxValue - minValue));
if (width) {
var offsetX = width * percent;
offsetX = Math.min(width, Math.max(0 , offsetX));
thumb.css('left', Math.max(0, offsetX - thumbWidth));
fill.css('width', offsetX);
} else {
thumb.css('left', percent * 100 + '%');
fill.css('width', percent * 100 + '%');
}
lastUpdValue = false;
}
});
@ -2095,6 +2080,13 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -2095,6 +2080,13 @@ angular.module('myApp.directives', ['myApp.filters'])
element.on('dragstart selectstart', cancelEvent);
element.on('mousedown', function (e) {
if (!width) {
width = wrap.width();
if (!width) {
console.error('empty width');
return cancelEvent(e);
}
}
stopMouseTrack();
lastMinPageX = e.pageX - e.offsetX;

29
app/js/filters.js

@ -56,7 +56,7 @@ angular.module('myApp.filters', ['myApp.i18n']) @@ -56,7 +56,7 @@ angular.module('myApp.filters', ['myApp.i18n'])
var cachedDates = {},
dateFilter = $filter('date');
return function (timestamp) {
return function (timestamp, extended) {
if (cachedDates[timestamp]) {
return cachedDates[timestamp];
@ -67,11 +67,12 @@ angular.module('myApp.filters', ['myApp.i18n']) @@ -67,11 +67,12 @@ angular.module('myApp.filters', ['myApp.i18n'])
format = 'shortTime';
if (diff > 518400000) { // 6 days
format = 'shortDate';
format = extended ? 'mediumDate' : 'shortDate';
}
else if (diff > 43200000) { // 12 hours
format = 'EEE';
format = extended ? 'EEEE' : 'EEE';
}
return cachedDates[timestamp] = dateFilter(ticks, format);
}
})
@ -120,6 +121,14 @@ angular.module('myApp.filters', ['myApp.i18n']) @@ -120,6 +121,14 @@ angular.module('myApp.filters', ['myApp.i18n'])
}
}])
.filter('durationRemains', function($filter) {
var durationFilter = $filter('duration');
return function (done, total) {
return '-' + durationFilter(total - done);
}
})
.filter('phoneNumber', [function() {
return function (phoneRaw) {
var nbsp = ' ';
@ -140,13 +149,13 @@ angular.module('myApp.filters', ['myApp.i18n']) @@ -140,13 +149,13 @@ angular.module('myApp.filters', ['myApp.i18n'])
return size + ' b';
}
else if (size < 1048576) {
return (Math.round(size / 1024 * 10) / 10) + ' Kb';
return Math.round(size / 1024) + ' Kb';
}
var mbs = size / 1048576;
if (progressing) {
mbs = mbs.toFixed(1);
} else {
mbs = (Math.round(mbs * 100) / 100);
mbs = (Math.round(mbs * 10) / 10);
}
return mbs + ' Mb';
}
@ -192,14 +201,14 @@ angular.module('myApp.filters', ['myApp.i18n']) @@ -192,14 +201,14 @@ angular.module('myApp.filters', ['myApp.i18n'])
if (diff < 60000) {
return _('relative_time_just_now');
}
if (diff < 3000000) {
var minutes = Math.ceil(diff / 60000);
if (diff < 3600000) {
var minutes = Math.floor(diff / 60000);
return langMinutesPluralize(minutes);
}
if (diff < 10000000) {
var hours = Math.ceil(diff / 3600000);
if (diff < 86400000) {
var hours = Math.floor(diff / 3600000);
return langHoursPluralize(hours);
}
return dateOrTimeFilter(timestamp);
return dateOrTimeFilter(timestamp, true);
}
})

1
app/js/locales/en-us.json

@ -329,6 +329,7 @@ @@ -329,6 +329,7 @@
"message_attach_video_video": "Video",
"message_attach_video_download": "Download",
"message_attach_video_save": "Save File",
"message_attach_video_play": "Play video",
"conversation_select_modal_title": "Select conversation",

182
app/js/services.js

@ -196,7 +196,6 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -196,7 +196,6 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
windowClass: 'user_modal_window mobile_modal'
});
};
$rootScope.openUser = openUser;
function importContact (phone, firstName, lastName) {
return MtpApiManager.invokeApi('contacts.importContacts', {
@ -528,9 +527,6 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -528,9 +527,6 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
});
}
$rootScope.openChat = openChat;
return {
saveApiChats: saveApiChats,
saveApiChat: saveApiChat,
@ -1276,7 +1272,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1276,7 +1272,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
fileName = 'video.mp4';
} else if (file.type.substr(0, 6) == 'audio/') {
attachType = 'audio';
fileName = 'audio.' + file.type.split('/')[1] || 'mp3';
fileName = 'audio.' + (file.type.split('/')[1] == 'ogg' ? 'ogg' : 'mp3');
} else {
attachType = 'document';
fileName = 'document.' + file.type.split('/')[1];
@ -2291,7 +2287,6 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2291,7 +2287,6 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
}
photo.full = full;
photo.fromUser = AppUsersManager.getUser(photo.user_id);
return photo;
}
@ -2334,19 +2329,17 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2334,19 +2329,17 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
};
FileManager.chooseSave(fileName, ext, mimeType).then(function (writableFileEntry) {
if (!writableFileEntry) {
return;
if (writableFileEntry) {
MtpApiFileManager.downloadFile(
fullPhotoSize.location.dc_id, inputFileLocation, fullPhotoSize.size, {
mime: mimeType,
toFileEntry: writableFileEntry
}).then(function (url) {
// console.log('file save done');
}, function (e) {
console.log('photo download failed', e);
});
}
MtpApiFileManager.downloadFile(
fullPhotoSize.location.dc_id, inputFileLocation, fullPhotoSize.size, {
mime: mimeType,
toFileEntry: writableFileEntry
}).then(function (url) {
// console.log('file save done');
}, function (e) {
console.log('photo download failed', e);
});
}, function () {
MtpApiFileManager.downloadFile(
fullPhotoSize.location.dc_id, inputFileLocation, fullPhotoSize.size, {mime: mimeType}
@ -2360,7 +2353,6 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2360,7 +2353,6 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
$rootScope.openPhoto = openPhoto;
return {
savePhoto: savePhoto,
preloadPhoto: preloadPhoto,
@ -2374,7 +2366,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2374,7 +2366,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
})
.service('AppVideoManager', function ($rootScope, $modal, $window, $timeout, MtpApiFileManager, AppUsersManager, FileManager) {
.service('AppVideoManager', function ($sce, $rootScope, $modal, $window, $timeout, MtpApiFileManager, AppUsersManager, FileManager) {
var videos = {},
videosForHistory = {},
windowW = $(window).width(),
@ -2399,8 +2391,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2399,8 +2391,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
}
var video = angular.copy(videos[videoID]),
width = Math.min(windowW - 80, Config.Mobile ? 210 : 200),
height = Math.min(windowH - 100, Config.Mobile ? 210 : 200),
width = Math.min(windowW - 80, Config.Mobile ? 210 : 150),
height = Math.min(windowH - 100, Config.Mobile ? 210 : 150),
thumbPhotoSize = video.thumb,
thumb = {
placeholder: 'img/placeholders/VideoThumbConversation.gif',
@ -2452,7 +2444,6 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2452,7 +2444,6 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
video.fullThumb = angular.copy(video.thumb);
video.fullThumb.width = full.width;
video.fullThumb.height = full.height;
video.fromUser = AppUsersManager.getUser(video.user_id);
return video;
}
@ -2462,7 +2453,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2462,7 +2453,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
scope.videoID = videoID;
scope.messageID = messageID;
var modalInstance = $modal.open({
return $modal.open({
templateUrl: templateUrl('video_modal'),
controller: 'VideoModalController',
scope: scope,
@ -2470,79 +2461,93 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2470,79 +2461,93 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
});
}
function downloadVideo (videoID, accessHash, popup) {
function updateVideoDownloaded (videoID) {
var video = videos[videoID],
historyVideo = videosForHistory[videoID] || video || {},
inputFileLocation = {
_: 'inputVideoFileLocation',
id: videoID,
access_hash: accessHash || video.access_hash
access_hash: video.access_hash
};
historyVideo.progress = {enabled: true, percent: 1, total: video.size};
// historyVideo.progress = {enabled: true, percent: 10, total: video.size};
function updateDownloadProgress (progress) {
if (historyVideo.downloaded === undefined) {
MtpApiFileManager.getDownloadedFile(inputFileLocation, video.size).then(function () {
historyVideo.downloaded = true;
}, function () {
historyVideo.downloaded = false;
});
}
}
function downloadVideo (videoID, toFileEntry) {
var video = videos[videoID],
historyVideo = videosForHistory[videoID] || video || {},
inputFileLocation = {
_: 'inputVideoFileLocation',
id: videoID,
access_hash: video.access_hash
};
historyVideo.progress = {enabled: !historyVideo.downloaded, percent: 1, total: video.size};
var downloadPromise = MtpApiFileManager.downloadFile(video.dc_id, inputFileLocation, video.size, {
mime: video.mime_type || 'video/ogg',
toFileEntry: toFileEntry
});
downloadPromise.then(function (url) {
delete historyVideo.progress;
historyVideo.url = $sce.trustAsResourceUrl(url);
historyVideo.downloaded = true;
console.log('video save done');
}, function (e) {
console.log('video download failed', e);
historyVideo.progress.enabled = false;
}, function (progress) {
console.log('dl progress', progress);
historyVideo.progress.enabled = true;
historyVideo.progress.done = progress.done;
historyVideo.progress.percent = Math.max(1, Math.floor(100 * progress.done / progress.total));
$rootScope.$broadcast('history_update');
}
});
var ext = 'mp4',
mimeType = 'video/mpeg4',
fileName = 'video' + videoID + '.' + ext;
historyVideo.progress.cancel = downloadPromise.cancel;
FileManager.chooseSave(fileName, ext, mimeType).then(function (writableFileEntry) {
if (!writableFileEntry) {
return;
}
return downloadPromise;
}
var downloadPromise = MtpApiFileManager.downloadFile(video.dc_id, inputFileLocation, video.size, {
mime: mimeType,
toFileEntry: writableFileEntry
});
downloadPromise.then(function (url) {
delete historyVideo.progress;
console.log('file save done');
}, function (e) {
console.log('video download failed', e);
historyVideo.progress.enabled = false;
}, updateDownloadProgress);
function saveVideoFile (videoID) {
var video = videos[videoID],
mimeType = video.mime_type || 'video/mpeg4',
fileExt = mimeType.split('.')[1] || 'mp4',
fileName = 't_video' + videoID + '.' + fileExt,
historyVideo = videosForHistory[videoID] || video || {};
historyVideo.progress.cancel = downloadPromise.cancel;
FileManager.chooseSave(fileName, fileExt, mimeType).then(function (writableFileEntry) {
if (writableFileEntry) {
downloadVideo(videoID, writableFileEntry);
}
}, function () {
var downloadPromise = MtpApiFileManager.downloadFile(video.dc_id, inputFileLocation, video.size, {mime: mimeType});
downloadPromise.then(function (url) {
delete historyVideo.progress;
if (popup) {
window.open(url, '_blank');
return
}
downloadVideo(videoID).then(function (url) {
FileManager.download(url, mimeType, fileName);
}, function (e) {
console.log('video download failed', e);
historyVideo.progress.enabled = false;
}, updateDownloadProgress);
historyVideo.progress.cancel = downloadPromise.cancel;
});
});
};
$rootScope.openVideo = openVideo;
$rootScope.downloadVideo = downloadVideo;
}
return {
saveVideo: saveVideo,
wrapForHistory: wrapForHistory,
wrapForFull: wrapForFull,
openVideo: openVideo
openVideo: openVideo,
updateVideoDownloaded: updateVideoDownloaded,
downloadVideo: downloadVideo,
saveVideoFile: saveVideoFile
}
})
.service('AppDocsManager', function ($rootScope, $modal, $window, $timeout, $q, MtpApiFileManager, FileManager) {
.service('AppDocsManager', function ($sce, $rootScope, $modal, $window, $timeout, $q, MtpApiFileManager, FileManager) {
var docs = {},
docsForHistory = {},
windowW = $(window).width(),
@ -2619,6 +2624,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2619,6 +2624,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
access_hash: doc.access_hash
};
// historyDoc.progress = {enabled: true, percent: 10, total: doc.size};
if (historyDoc.downloaded === undefined) {
MtpApiFileManager.getDownloadedFile(inputFileLocation, doc.size).then(function () {
historyDoc.downloaded = true;
@ -2637,7 +2644,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2637,7 +2644,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
access_hash: doc.access_hash
};
historyDoc.progress = {enabled: true, percent: 1, total: doc.size};
historyDoc.progress = {enabled: !historyDoc.downloaded, percent: 1, total: doc.size};
var downloadPromise = MtpApiFileManager.downloadFile(doc.dc_id, inputFileLocation, doc.size, {
mime: doc.mime_type,
@ -2646,7 +2653,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2646,7 +2653,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
downloadPromise.then(function (url) {
delete historyDoc.progress;
historyDoc.url = url;
historyDoc.url = $sce.trustAsResourceUrl(url);
historyDoc.downloaded = true;
console.log('file save done');
}, function (e) {
@ -2654,6 +2661,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2654,6 +2661,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
historyDoc.progress.enabled = false;
}, function (progress) {
console.log('dl progress', progress);
historyDoc.progress.enabled = true;
historyDoc.progress.done = progress.done;
historyDoc.progress.percent = Math.max(1, Math.floor(100 * progress.done / progress.total));
$rootScope.$broadcast('history_update');
@ -2683,12 +2691,9 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2683,12 +2691,9 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
var ext = (doc.file_name.split('.', 2) || [])[1] || '';
FileManager.chooseSave(doc.file_name, ext, doc.mime_type).then(function (writableFileEntry) {
if (!writableFileEntry) {
return;
if (writableFileEntry) {
downloadDoc(docID, writableFileEntry);
}
downloadDoc(docID, writableFileEntry).then(function () {
console.log('file save done');
});
}, function () {
downloadDoc(docID).then(function (url) {
FileManager.download(url, doc.mime_type, doc.file_name);
@ -2706,7 +2711,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2706,7 +2711,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
}
})
.service('AppAudioManager', function ($rootScope, $modal, $window, $timeout, $sce, MtpApiFileManager, FileManager) {
.service('AppAudioManager', function ($sce, $rootScope, $modal, $window, $timeout, MtpApiFileManager, FileManager) {
var audios = {};
var audiosForHistory = {};
@ -2733,6 +2738,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2733,6 +2738,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
access_hash: audio.access_hash
};
// historyAudio.progress = {enabled: !historyAudio.downloaded, percent: 10, total: audio.size};
if (historyAudio.downloaded === undefined) {
MtpApiFileManager.getDownloadedFile(inputFileLocation, audio.size).then(function () {
historyAudio.downloaded = true;
@ -2751,7 +2758,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2751,7 +2758,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
access_hash: audio.access_hash
};
historyAudio.progress = {enabled: true, percent: 1, total: audio.size};
historyAudio.progress = {enabled: !historyAudio.downloaded, percent: 1, total: audio.size};
var downloadPromise = MtpApiFileManager.downloadFile(audio.dc_id, inputFileLocation, audio.size, {
mime: audio.mime_type || 'audio/ogg',
@ -2760,7 +2767,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2760,7 +2767,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
downloadPromise.then(function (url) {
delete historyAudio.progress;
historyAudio.url = url;
historyAudio.url = $sce.trustAsResourceUrl(url);
historyAudio.downloaded = true;
console.log('audio save done');
}, function (e) {
@ -2768,6 +2775,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2768,6 +2775,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
historyAudio.progress.enabled = false;
}, function (progress) {
console.log('dl progress', progress);
historyAudio.progress.enabled = true;
historyAudio.progress.done = progress.done;
historyAudio.progress.percent = Math.max(1, Math.floor(100 * progress.done / progress.total));
$rootScope.$broadcast('history_update');
@ -2780,18 +2788,18 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2780,18 +2788,18 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
function saveAudioFile (audioID) {
var audio = audios[audioID],
mimeType = audio.mime_type || 'audio/ogg',
fileExt = mimeType.split('.')[1] || 'ogg',
fileName = 't_audio' + audioID + '.' + fileExt,
historyAudio = audiosForHistory[audioID] || audio || {};
FileManager.chooseSave(audio.file_name, 'ogg', audio.mime_type || 'audio/ogg').then(function (writableFileEntry) {
if (!writableFileEntry) {
return;
FileManager.chooseSave(fileName, fileExt, mimeType).then(function (writableFileEntry) {
if (writableFileEntry) {
downloadAudio(audioID, writableFileEntry);
}
downloadAudio(audioID, writableFileEntry).then(function () {
console.log('file save done');
});
}, function () {
downloadAudio(audioID).then(function (url) {
FileManager.download(url, audio.mime_type, audio.file_name);
FileManager.download(url, mimeType, fileName);
});
});
}

36
app/partials/desktop/audio_player.html

@ -1,27 +1,35 @@ @@ -1,27 +1,35 @@
<div class="audio_player_wrap clearfix">
<button class="btn btn-primary pull-left audio_player_button" ng-click="togglePlay()">
<i class="icon audio_player_btn_icon" ng-class="{audio_player_btn_icon_pause: mediaPlayer.player.playing, audio_player_btn_icon_cancel: audio.progress.enabled}"></i>
</button>
<a class="im_message_file_button" ng-click="togglePlay()" ng-class="{im_message_file_button_dl_audio: audio.downloaded}">
<i class="im_message_file_button_icon" ng-class="{audio_player_btn_icon_pause: mediaPlayer.player.playing}"></i>
</a>
<div class="audio_player_title_wrap">
<div class="audio_player_meta pull-right" ng-if="audio.downloaded &amp;&amp; (mediaPlayer.player.duration || audio.duration)" ng-switch="mediaPlayer.player.playing || mediaPlayer.player.currentTime > 0">
<span ng-switch-when="true" class="audio_player_duration" ng-bind="mediaPlayer.player.currentTime | durationRemains : (mediaPlayer.player.duration || audio.duration)"></span>
<span ng-switch-default class="audio_player_duration" ng-bind="mediaPlayer.player.duration || audio.duration | duration"></span>
</div>
<a ng-click="download()" class="audio_player_title" ng-switch="::audio.file_name.length > 0">
<span ng-switch-when="true" ng-bind="::audio.file_name"></span>
<span ng-switch-default my-i18n="message_attach_audio_message"></span>
</a>
<div class="audio_player_meta" ng-switch="audio.progress.enabled ? 'progress' : (!mediaPlayer.player.duration &amp;&amp; !audio.duration ? 'size' : '')">
<span ng-switch-when="progress" class="audio_player_size" ng-bind="audio.progress | formatSizeProgress"></span>
<span ng-switch-when="size" class="audio_player_size" ng-bind="audio.size | formatSize"></span>
<span ng-switch-default class="audio_player_duration" ng-bind="(mediaPlayer.player.playing || mediaPlayer.player.currentTime > 0) ? mediaPlayer.player.currentTime : (mediaPlayer.player.duration || audio.duration) | duration"></span>
<div class="audio_player_meta" ng-if="!audio.downloaded || !(mediaPlayer.player.duration || audio.duration)" ng-switch="audio.progress.enabled">
<span ng-switch-when="true" class="audio_player_size" ng-bind="audio.progress | formatSizeProgress"></span>
<span ng-switch-default class="audio_player_size" ng-bind="audio.size | formatSize"></span>
</div>
</div>
<div class="audio_player_actions" ng-if="!audio.progress.enabled &amp;&amp; !audio.url">
<a ng-click="togglePlay()" my-i18n="message_attach_audio_play"></a>
<div class="audio_player_actions" ng-if="!audio.progress.enabled &amp;&amp; !audio.downloaded">
<a ng-if="audio._ == 'document'" ng-click="download()" my-i18n="message_attach_document_download"></a>
<a ng-click="togglePlay()" my-i18n="message_attach_audio_play"></a>
</div>
<div class="audio_player_progress_wrap" ng-if="audio.progress.enabled || audio.url" ng-switch="audio.progress.enabled">
<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>
<div ng-switch-default>
<div class="audio_player_progress_wrap" ng-if="audio.progress.enabled || audio.downloaded" ng-switch="audio.progress.enabled">
<div ng-switch-when="true" class="clearfix im_message_cancelable_progress_wrap">
<a class="im_message_media_progress_cancel pull-right" ng-click="audio.progress.cancel()" my-i18n="modal_cancel"></a>
<div class="im_message_download_progress_wrap">
<div class="progress tg_down_progress">
<div class="progress-bar progress-bar-success" ng-style="{width: audio.progress.percent + '%'}"></div>
</div>
</div>
</div>
<div ng-switch-default class="im_message_playback_progress_wrap">
<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>

4
app/partials/desktop/full_gif.html

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
<a class="img_gif_with_progress_wrap" ng-click="toggle($event)">
<div class="img_gif_image_wrap" ng-switch="document.url &amp;&amp; isActive">
<div class="img_gif_image_wrap" ng-switch="document.downloaded &amp;&amp; isActive">
<img ng-switch-when="true" class="img_gif_image" ng-src="{{document.url}}" />
<img ng-switch-default class="img_gif_thumb" my-load-thumb thumb="document.thumb" />
@ -17,7 +17,7 @@ @@ -17,7 +17,7 @@
<div ng-switch-default class="img_gif_info_wrap">
<div class="img_gif_label pull-left">GIF</div>
<div ng-if="!document.url" class="img_gif_size pull-right" ng-bind="::document.size | formatSize"></div>
<div ng-if="!document.downloaded" class="img_gif_size pull-right" ng-bind="::document.size | formatSize"></div>
</div>
</div>

14
app/partials/desktop/full_video.html

@ -1,22 +1,22 @@ @@ -1,22 +1,22 @@
<div class="img_fullsize_with_progress_wrap" ng-style="{width: video.full.width + 'px', height: video.full.height + 'px'}">
<div class="img_fullsize_progress_overlay" ng-show="progress.enabled">
<div class="img_fullsize_progress_overlay" ng-show="video.progress.enabled">
<div class="img_fullsize_progress_wrap" ng-style="{width: video.full.width + 'px', height: video.full.height + 'px'}">
<div class="img_fullsize_progress progress tg_progress">
<div class="progress-bar progress-bar-success" style="width: {{progress.percent}}%"></div>
<div class="progress-bar progress-bar-success" style="width: {{video.progress.percent}}%"></div>
</div>
</div>
</div>
<div class="img_fullsize_wrap" ng-if="!player.src">
<div class="img_fullsize_wrap" ng-if="!video.url">
<img
class="img_fullsize"
my-load-thumb
thumb="video.fullThumb"
/>
</div>
<div class="video_full_player" ng-if="player.src">
<embed ng-src="{{player.src}}" width="{{video.full.width}}" height="{{video.full.height}}" autoplay="true" CONTROLLER="TRUE" SHOWCONTROLS="TRUE" controller="true" loop="false" pluginspace="http://www.apple.com/quicktime/" ng-if="player.quicktime"/>
<video width="{{video.full.width}}" height="{{video.full.height}}" controls autoplay ng-if="!player.quicktime">
<source ng-src="{{player.src}}" type="video/mp4">
<div class="video_full_player" ng-if="video.url" ng-switch="player.quicktime">
<embed ng-switch-when="true" ng-src="{{video.url}}" width="{{video.full.width}}" height="{{video.full.height}}" autoplay="true" CONTROLLER="TRUE" SHOWCONTROLS="TRUE" controller="true" loop="false" pluginspace="http://www.apple.com/quicktime/" />
<video ng-switch-default width="{{video.full.width}}" height="{{video.full.height}}" controls autoplay >
<source ng-src="{{video.url}}" type="video/mp4">
</video>
</div>
<div class="video_full_error_wrap" ng-if="error">

2
app/partials/desktop/message.html

@ -51,7 +51,7 @@ @@ -51,7 +51,7 @@
<div ng-if="::historyMessage.media ? true : false" class="im_message_media" ng-switch="historyMessage.media._">
<div ng-switch-when="messageMediaPhoto" my-message-photo></div>
<div ng-switch-when="messageMediaVideo" my-message-video></div>
<div ng-switch-when="messageMediaVideo" my-message-video="historyMessage.media.video" message-id="historyMessage.id"></div>
<div ng-switch-when="messageMediaDocument" my-message-document="historyMessage.media.document" message-id="historyMessage.id"></div>
<div ng-switch-when="messageMediaAudio" class="im_message_audio" my-audio-player audio="historyMessage.media.audio"></div>
<div ng-switch-when="messageMediaGeo" my-message-map></div>

2
app/partials/desktop/message_attach_document.html

@ -32,7 +32,7 @@ @@ -32,7 +32,7 @@
<a ng-switch-default href="" ng-click="docSave()" my-i18n="message_attach_document_download"></a>
<a ng-if="::document.withPreview" href="" ng-click="docOpen()" my-i18n="message_attach_document_open"></a>
</div>
<div class="clearfix cancelable_progress_wrap" ng-if="document.progress.enabled">
<div class="clearfix im_message_cancelable_progress_wrap" ng-if="document.progress.enabled">
<a class="im_message_media_progress_cancel pull-right" ng-click="document.progress.cancel()" my-i18n="modal_cancel"></a>
<div class="im_message_download_progress_wrap">
<div class="progress tg_down_progress">

8
app/partials/desktop/message_attach_pending.html

@ -1,14 +1,16 @@ @@ -1,14 +1,16 @@
<div class="im_message_document im_message_upload_file" ng-class="::'im_message_upload_' + historyMessage.media.type">
<i class="icon" ng-class="::'icon-' + historyMessage.media.type"></i>
<div class="im_message_file_button im_message_file_button_upload">
<i class="im_message_file_button_icon"></i>
</div>
<div class="im_message_document_info">
<div class="im_message_document_name_wrap">
<span class="im_message_document_name" ng-bind="::historyMessage.media.file_name"></span>
<span class="im_message_document_size" ng-if="historyMessage.media.progress" ng-bind="historyMessage.media.progress | formatSizeProgress"></span>
</div>
<div class="clearfix cancelable_progress_wrap">
<div class="clearfix im_message_cancelable_progress_wrap">
<a class="im_message_media_progress_cancel pull-right" ng-click="historyMessage.media.progress.cancel()" my-i18n="modal_cancel"></a>
<div class="im_message_download_progress_wrap">
<div class="progress tg_down_progress">
<div class="progress tg_up_progress">
<div class="progress-bar progress-bar-success" role="progressbar" ng-style="{width: historyMessage.media.progress.percent + '%'}"></div>
</div>
</div>

25
app/partials/desktop/message_attach_video.html

@ -1,29 +1,32 @@ @@ -1,29 +1,32 @@
<div class="im_message_video im_message_document_thumbed">
<a class="im_message_video_thumb" href="" ng-click="openVideo(historyMessage.media.video.id, historyMessage.id)" ng-style="::{width: historyMessage.media.video.thumb.width + 'px'}">
<span class="im_message_video_duration" ng-bind="::historyMessage.media.video.duration | duration"></span>
<a class="im_message_video_thumb" href="" ng-click="videoOpen()" ng-style="::{width: video.thumb.width + 'px'}">
<span class="im_message_video_duration" ng-bind="::video.duration | duration"></span>
<i class="icon icon-videoplay"></i>
<img
class="im_message_video_thumb"
my-load-thumb
thumb="historyMessage.media.video.thumb"
thumb="video.thumb"
/>
</a>
<div class="im_message_document_info">
<div class="im_message_document_name_wrap">
<span class="im_message_document_name" my-i18n="message_attach_video_video"></span>
<span class="im_message_document_size" ng-if="!historyMessage.media.video.progress.enabled" ng-bind="::historyMessage.media.video.size | formatSize"></span>
<span class="im_message_document_size" ng-if="historyMessage.media.video.progress.enabled" ng-bind="historyMessage.media.video.progress | formatSizeProgress"></span>
<span class="im_message_document_size" ng-if="!video.progress.enabled" ng-bind="::video.size | formatSize"></span>
<span class="im_message_document_size" ng-if="video.progress.enabled" ng-bind="video.progress | formatSizeProgress"></span>
</div>
<div class="im_message_document_actions" ng-if="!historyMessage.media.video.progress.enabled">
<a href="" ng-click="downloadVideo(historyMessage.media.video.id)" my-i18n="message_attach_video_download"></a>
<a href="" ng-click="openVideo(historyMessage.media.video.id, historyMessage.id)" my-i18n="message_attach_video_play"></a>
<div class="im_message_document_actions" ng-if="!video.progress.enabled">
<a href="" ng-click="videoSave()" ng-switch="video.downloaded">
<span ng-switch-when="true" my-i18n="message_attach_video_save"></span>
<span ng-switch-default my-i18n="message_attach_video_download"></span>
</a>
<a href="" ng-click="videoOpen()" my-i18n="message_attach_video_play"></a>
</div>
<div class="clearfix cancelable_progress_wrap" ng-if="historyMessage.media.video.progress.enabled">
<a class="im_message_media_progress_cancel pull-right" ng-click="historyMessage.media.video.progress.cancel()" my-i18n="modal_cancel"></a>
<div class="clearfix im_message_cancelable_progress_wrap" ng-if="video.progress.enabled">
<a class="im_message_media_progress_cancel pull-right" ng-click="video.progress.cancel()" my-i18n="modal_cancel"></a>
<div class="im_message_download_progress_wrap">
<div class="progress tg_down_progress">
<div class="progress-bar progress-bar-success" ng-style="{width: historyMessage.media.video.progress.percent + '%'}"></div>
<div class="progress-bar progress-bar-success" ng-style="{width: video.progress.percent + '%'}"></div>
</div>
</div>
</div>

2
app/partials/desktop/settings_modal.html

@ -97,7 +97,7 @@ @@ -97,7 +97,7 @@
<i class="icon-volume-inner icon-volume-inner3"></i>
<i class="icon-volume-inner icon-volume-inner4"></i>
</span>
<div class="settings_volume_slider" my-slider slider-model="notify.volume" slider-min="1" slider-max="10"></div>
<div class="settings_volume_slider" my-slider slider-model="notify.volume"></div>
</div>
</div>

6
app/partials/mobile/full_gif.html

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
<a class="img_gif_with_progress_wrap" ng-click="toggle()">
<a class="img_gif_with_progress_wrap" ng-click="toggle($event)">
<div class="img_gif_image_wrap" ng-switch="document.url &amp;&amp; isActive">
<div class="img_gif_image_wrap" ng-switch="document.downloaded &amp;&amp; isActive">
<img ng-switch-when="true" class="img_gif_image" ng-src="{{document.url}}" />
<img ng-switch-default class="img_gif_thumb" my-load-thumb thumb="document.thumb" />
@ -17,7 +17,7 @@ @@ -17,7 +17,7 @@
<div ng-switch-default class="img_gif_info_wrap">
<div class="img_gif_label pull-left">GIF</div>
<div ng-if="!document.url" class="img_gif_size pull-right" ng-bind="::document.size | formatSize"></div>
<div ng-if="!document.downloaded" class="img_gif_size pull-right" ng-bind="::document.size | formatSize"></div>
</div>
</div>

14
app/partials/mobile/full_video.html

@ -1,22 +1,22 @@ @@ -1,22 +1,22 @@
<div class="img_fullsize_with_progress_wrap" ng-style="{width: video.full.width + 'px', height: video.full.height + 'px'}">
<div class="img_fullsize_progress_overlay" ng-show="progress.enabled">
<div class="img_fullsize_progress_overlay" ng-show="video.progress.enabled">
<div class="img_fullsize_progress_wrap" ng-style="{width: video.full.width + 'px', height: video.full.height + 'px'}">
<div class="img_fullsize_progress progress tg_progress">
<div class="progress-bar progress-bar-success" style="width: {{progress.percent}}%"></div>
<div class="progress-bar progress-bar-success" style="width: {{video.progress.percent}}%"></div>
</div>
</div>
</div>
<div class="img_fullsize_wrap" ng-if="!player.src">
<div class="img_fullsize_wrap" ng-if="!video.url">
<img
class="img_fullsize"
my-load-thumb
thumb="video.fullThumb"
/>
</div>
<div class="video_full_player" ng-if="player.src">
<embed ng-src="{{player.src}}" width="{{video.full.width}}" height="{{video.full.height}}" autoplay="true" CONTROLLER="TRUE" SHOWCONTROLS="TRUE" controller="true" loop="false" pluginspace="http://www.apple.com/quicktime/" ng-if="player.quicktime"/>
<video width="{{video.full.width}}" height="{{video.full.height}}" controls autoplay ng-if="!player.quicktime">
<source ng-src="{{player.src}}" type="video/mp4">
<div class="video_full_player" ng-if="video.url" ng-switch="player.quicktime">
<embed ng-switch-when="true" ng-src="{{video.url}}" width="{{video.full.width}}" height="{{video.full.height}}" autoplay="true" CONTROLLER="TRUE" SHOWCONTROLS="TRUE" controller="true" loop="false" pluginspace="http://www.apple.com/quicktime/" />
<video ng-switch-default width="{{video.full.width}}" height="{{video.full.height}}" controls autoplay >
<source ng-src="{{video.url}}" type="video/mp4">
</video>
</div>
<div class="video_full_error_wrap" ng-if="error">

2
app/partials/mobile/message.html

@ -41,7 +41,7 @@ @@ -41,7 +41,7 @@
<div ng-if="::historyMessage.media || false" class="im_message_media" ng-switch="historyMessage.media._">
<div ng-switch-when="messageMediaPhoto" my-message-photo></div>
<div ng-switch-when="messageMediaVideo" my-message-video></div>
<div ng-switch-when="messageMediaVideo" my-message-video="historyMessage.media.video" message-id="historyMessage.id"></div>
<div ng-switch-when="messageMediaDocument" my-message-document="historyMessage.media.document" message-id="historyMessage.id"></div>
<div ng-switch-when="messageMediaAudio" class="im_message_audio" my-audio-player audio="historyMessage.media.audio"></div>
<div ng-switch-when="messageMediaGeo" my-message-map></div>

37
app/partials/mobile/message_attach_document.html

@ -1,39 +1,42 @@ @@ -1,39 +1,42 @@
<div ng-switch="::historyMessage.media.document.isSpecial">
<div ng-switch="::document.isSpecial">
<div ng-switch-when="gif" my-load-gif document="historyMessage.media.document"></div>
<div ng-switch-when="gif" my-load-gif document="document"></div>
<div ng-switch-when="audio" class="im_message_audio">
<div my-audio-player audio="historyMessage.media.document"></div>
<div my-audio-player audio="document"></div>
</div>
<div ng-switch-default class="im_message_document" ng-class="{im_message_document_thumbed: !!historyMessage.media.document.thumb, im_message_document_progress: historyMessage.media.document.progress.enabled}">
<div ng-switch-default class="im_message_document clearfix" ng-class="{im_message_document_thumbed: !!document.thumb, im_message_document_progress: document.progress.enabled}">
<a href="" ng-click="downloadDoc(historyMessage.media.document.id, historyMessage.media.document.withPreview)" ng-class="{im_message_document_link_disabled: historyMessage.media.document.progress.enabled}">
<i class="icon icon-document" ng-if="::!historyMessage.media.document.thumb"></i>
<div class="im_message_document_thumb_wrap" ng-if="::historyMessage.media.document.thumb">
<a ng-if="::!document.thumb" class="im_message_file_button" ng-click="docOpen()" ng-class="{im_message_file_button_dl_doc: document.downloaded}">
<i class="im_message_file_button_icon"></i>
</a>
<a ng-if="::document.thumb" ng-click="docOpen()">
<div class="im_message_document_thumb_wrap">
<img
class="im_message_document_thumb"
my-load-thumb
thumb="historyMessage.media.document.thumb"
thumb="document.thumb"
/>
</div>
</a>
<div class="im_message_document_info">
<div class="im_message_document_name_wrap">
<span class="im_message_document_name" ng-bind="::historyMessage.media.document.file_name"></span>
<span class="im_message_document_size" ng-if="!historyMessage.media.document.progress.enabled" ng-bind="::historyMessage.media.document.size | formatSize"></span>
<span class="im_message_document_size" ng-if="historyMessage.media.document.progress.enabled" ng-bind="historyMessage.media.document.progress | formatSizeProgress"></span>
<span class="im_message_document_name" ng-bind="::document.file_name"></span>
<span class="im_message_document_size" ng-if="!document.progress.enabled" ng-bind="::document.size | formatSize"></span>
<span class="im_message_document_size" ng-if="document.progress.enabled" ng-bind="document.progress | formatSizeProgress"></span>
</div>
<div class="im_message_document_actions" ng-if="!historyMessage.media.document.progress.enabled">
<a href="" ng-click="downloadDoc(historyMessage.media.document.id)" my-i18n="message_attach_document_download"></a>
<a href="" ng-click="downloadDoc(historyMessage.media.document.id, 1)" ng-if="::historyMessage.media.document.withPreview" my-i18n="message_attach_document_open"></a>
<div class="im_message_document_actions" ng-if="!document.progress.enabled" ng-switch="document.downloaded">
<a ng-switch-when="true" href="" ng-click="docSave()" my-i18n="message_attach_document_save"></a>
<a ng-switch-default href="" ng-click="docSave()" my-i18n="message_attach_document_download"></a>
<a ng-if="::document.withPreview" href="" ng-click="docOpen()" my-i18n="message_attach_document_open"></a>
</div>
<div class="clearfix cancelable_progress_wrap" ng-if="historyMessage.media.document.progress.enabled">
<a class="im_message_media_progress_cancel pull-right" ng-click="historyMessage.media.document.progress.cancel()" my-i18n="modal_cancel"></a>
<div class="clearfix im_message_cancelable_progress_wrap" ng-if="document.progress.enabled">
<a class="im_message_media_progress_cancel pull-right" ng-click="document.progress.cancel()" my-i18n="modal_cancel"></a>
<div class="im_message_download_progress_wrap">
<div class="progress tg_down_progress">
<div class="progress-bar progress-bar-success" ng-style="{width: historyMessage.media.document.progress.percent + '%'}"></div>
<div class="progress-bar progress-bar-success" ng-style="{width: document.progress.percent + '%'}"></div>
</div>
</div>
</div>

2
app/partials/mobile/message_attach_pending.html

@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
<span class="im_message_document_name" ng-bind="::historyMessage.media.file_name"></span>
<span class="im_message_document_size" ng-if="historyMessage.media.progress" ng-bind="historyMessage.media.progress | formatSizeProgress"></span>
</div>
<div class="clearfix cancelable_progress_wrap">
<div class="clearfix im_message_cancelable_progress_wrap">
<a class="im_message_media_progress_cancel pull-right" ng-click="historyMessage.media.progress.cancel()" my-i18n="modal_cancel"></a>
<div class="im_message_download_progress_wrap">
<div class="progress tg_down_progress">

6
app/partials/mobile/message_attach_video.html

@ -1,11 +1,11 @@ @@ -1,11 +1,11 @@
<div class="im_message_video im_message_document_thumbed">
<a class="im_message_video_thumb" href="" ng-click="openVideo(historyMessage.media.video.id, historyMessage.id)" ng-style="::{width: historyMessage.media.video.thumb.width + 'px'}">
<span class="im_message_video_duration" ng-bind="::historyMessage.media.video.duration | duration"></span>
<a class="im_message_video_thumb" href="" ng-click="videoOpen()" ng-style="::{width: video.thumb.width + 'px'}">
<span class="im_message_video_duration" ng-bind="::video.duration | duration"></span>
<i class="icon icon-videoplay"></i>
<img
class="im_message_video_thumb"
my-load-thumb
thumb="historyMessage.media.video.thumb"
thumb="video.thumb"
/>
</a>
</div>

2
app/partials/mobile/photo_modal.html

@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
</div>
<p class="media_modal_info">
<span class="media_modal_author" ng-bind-html="::photo.fromUser.rFullName"></span>, <span ng-bind="photo.date | dateOrTime"></span>
<a class="media_modal_author" my-user-link="photo.user_id"></a>, <span ng-bind="photo.date | dateOrTime"></span>
</p>
</div>

1
app/partials/mobile/slider.html

@ -0,0 +1 @@ @@ -0,0 +1 @@
../desktop/slider.html

2
app/partials/mobile/video_modal.html

@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
</div>
<p class="media_modal_info">
<span class="media_modal_author" ng-bind-html="video.fromUser.rFullName"></span>, <span ng-bind="video.date | dateOrTime"></span>
<a class="media_modal_author" my-user-link="video.user_id"></a>, <span ng-bind="video.date | dateOrTime"></span>
</p>
</div>

Loading…
Cancel
Save