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. 128
      app/js/directives.js
  5. 29
      app/js/filters.js
  6. 1
      app/js/locales/en-us.json
  7. 152
      app/js/services.js
  8. 32
      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 {
z-index: 1; z-index: 1;
} }
.im_message_video,
.im_message_document, .im_message_document,
.im_message_upload_file { .im_message_upload_file,
.im_message_audio {
margin-top: 3px; margin-top: 3px;
/*border-radius: 3px;*/ width: 317px;
/*display: inline-block;*/
width: 342px;
} }
.im_message_audio { .im_message_audio {
margin-top: 3px; margin-top: 3px;
@ -1366,6 +1366,29 @@ div.im_message_video_thumb {
height: 18px; height: 18px;
margin: 12px 13px; 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_message_selected .icon-document,
.im_history_selectable .im_message_outer_wrap:hover .icon-document { .im_history_selectable .im_message_outer_wrap:hover .icon-document {
@ -1403,11 +1426,11 @@ img.im_message_document_thumb {
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
width: 290px; width: 265px;
padding: 0 0 1px; padding: 0 0 1px;
} }
.im_message_document_actions { .im_message_document_actions {
width: 290px; width: 265px;
} }
@ -1415,7 +1438,7 @@ img.im_message_document_thumb {
color: #3a6d99; color: #3a6d99;
display: inline-block; display: inline-block;
font-weight: bold; font-weight: bold;
max-width: 200px; max-width: 170px;
overflow: hidden; overflow: hidden;
vertical-align: text-top; vertical-align: text-top;
white-space: nowrap; white-space: nowrap;
@ -1424,42 +1447,12 @@ img.im_message_document_thumb {
.im_message_document_size { .im_message_document_size {
color: #999; color: #999;
padding-left: 2px; padding-left: 2px;
vertical-align: text-top;
} }
.im_message_document_actions a, .im_message_document_actions a,
.audio_player_actions a { .audio_player_actions a {
margin-right: 10px; 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 { .audio_player_title_wrap {
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
@ -1467,11 +1460,12 @@ img.im_message_document_thumb {
padding: 1px 0 1px; padding: 1px 0 1px;
line-height: 16px; line-height: 16px;
height: 19px; height: 19px;
width: 200px;
} }
.audio_player_title { .audio_player_title {
display: inline-block; display: inline-block;
font-weight: bold; font-weight: bold;
max-width: 200px; max-width: 85px;
overflow: hidden; overflow: hidden;
vertical-align: text-top; vertical-align: text-top;
white-space: nowrap; white-space: nowrap;
@ -1487,10 +1481,14 @@ img.im_message_document_thumb {
color: #999; color: #999;
padding-left: 2px; padding-left: 2px;
} }
.audio_player_actions {
margin-top: 3px;
}
.audio_player_seek_slider { .audio_player_seek_slider {
float: left; float: left;
margin-right: 17px; margin-right: 15px;
width: 236px; width: 200px;
} }
.audio_player_seek_slider .tg_slider_wrap { .audio_player_seek_slider .tg_slider_wrap {
height: 16px; height: 16px;
@ -1508,6 +1506,7 @@ img.im_message_document_thumb {
margin: 6px 0; margin: 6px 0;
background: rgba(218,228,234,0.50); background: rgba(218,228,234,0.50);
height: 4px; height: 4px;
border-radius: 0;
} }
.audio_player_seek_slider .tg_slider_track_fill { .audio_player_seek_slider .tg_slider_track_fill {
background: #6490b1; background: #6490b1;
@ -1546,49 +1545,56 @@ img.im_message_document_thumb {
width: 0; width: 0;
} }
.im_message_upload_progress_wrap,
.im_message_download_progress_wrap {
margin-top: 5px;
width: 290px;
}
.audio_player_progress_wrap { .audio_player_progress_wrap {
margin-top: 4px;
/*max-width: 290px;*/
width: 303px;
overflow: hidden; overflow: hidden;
} }
.audio_player_progress_wrap .tg_down_progress { .audio_player_progress_wrap .tg_down_progress {
margin-top: 5px; 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_document_name_wrap,
.im_message_document_thumbed .im_message_upload_progress_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_download_progress_wrap,
.im_message_document_thumbed .im_message_document_actions { .im_message_document_thumbed .im_message_document_actions {
width: 230px; width: 207px;
} }
.im_message_document_thumbed .im_message_document_name { .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_document_name_wrap,
.im_message_video .im_message_download_progress_wrap, .im_message_video .im_message_download_progress_wrap,
.im_message_video .im_message_document_actions { .im_message_video .im_message_document_actions {
width: 150px; width: 152px;
} }
.im_message_video .im_message_document_name_wrap { .im_message_video .im_message_document_name_wrap {
margin-top: 5px; margin-top: 5px;
} }
.im_message_cancelable_progress_wrap,
.im_message_playback_progress_wrap {
margin-top: 4px;
/*width: 265px;*/
}
.im_message_media_progress_cancel { .im_message_media_progress_cancel {
font-size: 11px; margin-left: 15px;
margin-left: 10px;
line-height: 100%; line-height: 100%;
width: 50px;
display: block;
overflow: hidden;
} }
.tg_up_progress, .tg_up_progress,
.tg_down_progress, .tg_down_progress {
.tg_play_progress { height: 4px;
height: 5px;
margin: 0; margin: 0;
padding: 0; padding: 0;
background: rgba(218,228,234,0.50); background: rgba(218,228,234,0.50);
@ -1598,26 +1604,15 @@ img.im_message_document_thumb {
box-shadow: none; box-shadow: none;
} }
.tg_up_progress .progress-bar, .tg_up_progress .progress-bar,
.tg_down_progress .progress-bar, .tg_down_progress .progress-bar {
.tg_play_progress .progress-bar { height: 4px;
height: 5px; line-height: 4px;
line-height: 5px;
background: #6B9ABD; background: #6B9ABD;
border-radius: 0; border-radius: 0;
overflow: hidden; overflow: hidden;
-webkit-box-shadow: none; -webkit-box-shadow: none;
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;
}
@ -2758,3 +2753,8 @@ ce671b orange
line-height: 160%; line-height: 160%;
margin: 25px 0 30px; margin: 25px 0 30px;
} }
#nacl_listener {
position: absolute;
left: -10000px;
}

8
app/css/mobile.css

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

21
app/js/controllers.js

@ -316,7 +316,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
ChangelogNotifyService.checkUpdate(); 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); $scope.$on('$routeUpdate', updateCurDialog);
@ -400,9 +400,9 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.showPeerInfo = function () { $scope.showPeerInfo = function () {
if ($scope.curDialog.peerID > 0) { if ($scope.curDialog.peerID > 0) {
$rootScope.openUser($scope.curDialog.peerID) AppUsersManager.openUser($scope.curDialog.peerID)
} else if ($scope.curDialog.peerID < 0) { } 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'])
} }
}); });
$scope.notify = {}; $scope.notify = {volume: 0.5};
$scope.send = {}; $scope.send = {};
$scope.$watch('photo.file', onPhotoSelected); $scope.$watch('photo.file', onPhotoSelected);
@ -2210,31 +2210,30 @@ angular.module('myApp.controllers', ['myApp.i18n'])
if (settings[1]) { if (settings[1]) {
$scope.notify.volume = 0; $scope.notify.volume = 0;
} else if (settings[3] !== false) { } 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 { } else {
$scope.notify.volume = 5; $scope.notify.volume = 0.5;
} }
$scope.notify.canVibrate = NotificationsManager.getVibrateSupport(); $scope.notify.canVibrate = NotificationsManager.getVibrateSupport();
$scope.notify.vibrate = !settings[4]; $scope.notify.vibrate = !settings[4];
$scope.notify.volumeOf4 = function () { $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 () { $scope.toggleSound = function () {
if ($scope.notify.volume) { if ($scope.notify.volume) {
$scope.notify.volume = 0; $scope.notify.volume = 0;
} else { } else {
$scope.notify.volume = 5; $scope.notify.volume = 0.5;
} }
} }
var testSoundPromise; var testSoundPromise;
$scope.$watch('notify.volume', function (newValue, oldValue) { $scope.$watch('notify.volume', function (newValue, oldValue) {
if (newValue !== oldValue) { if (newValue !== oldValue) {
var storeVolume = newValue / 10; Storage.set({notify_volume: newValue});
Storage.set({notify_volume: storeVolume});
Storage.remove('notify_nosound'); Storage.remove('notify_nosound');
NotificationsManager.clear(); NotificationsManager.clear();
@ -2242,7 +2241,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$timeout.cancel(testSoundPromise); $timeout.cancel(testSoundPromise);
} }
testSoundPromise = $timeout(function () { testSoundPromise = $timeout(function () {
NotificationsManager.testSound(storeVolume); NotificationsManager.testSound(newValue);
}, 500); }, 500);
} }
}); });

128
app/js/directives.js

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

29
app/js/filters.js

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

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

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

152
app/js/services.js

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

32
app/partials/desktop/audio_player.html

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

4
app/partials/desktop/full_gif.html

@ -1,6 +1,6 @@
<a class="img_gif_with_progress_wrap" ng-click="toggle($event)"> <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-when="true" class="img_gif_image" ng-src="{{document.url}}" />
<img ng-switch-default class="img_gif_thumb" my-load-thumb thumb="document.thumb" /> <img ng-switch-default class="img_gif_thumb" my-load-thumb thumb="document.thumb" />
@ -17,7 +17,7 @@
<div ng-switch-default class="img_gif_info_wrap"> <div ng-switch-default class="img_gif_info_wrap">
<div class="img_gif_label pull-left">GIF</div> <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>
</div> </div>

14
app/partials/desktop/full_video.html

@ -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_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_wrap" ng-style="{width: video.full.width + 'px', height: video.full.height + 'px'}">
<div class="img_fullsize_progress progress tg_progress"> <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>
</div> </div>
<div class="img_fullsize_wrap" ng-if="!player.src"> <div class="img_fullsize_wrap" ng-if="!video.url">
<img <img
class="img_fullsize" class="img_fullsize"
my-load-thumb my-load-thumb
thumb="video.fullThumb" thumb="video.fullThumb"
/> />
</div> </div>
<div class="video_full_player" ng-if="player.src"> <div class="video_full_player" ng-if="video.url" ng-switch="player.quicktime">
<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"/> <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 width="{{video.full.width}}" height="{{video.full.height}}" controls autoplay ng-if="!player.quicktime"> <video ng-switch-default width="{{video.full.width}}" height="{{video.full.height}}" controls autoplay >
<source ng-src="{{player.src}}" type="video/mp4"> <source ng-src="{{video.url}}" type="video/mp4">
</video> </video>
</div> </div>
<div class="video_full_error_wrap" ng-if="error"> <div class="video_full_error_wrap" ng-if="error">

2
app/partials/desktop/message.html

@ -51,7 +51,7 @@
<div ng-if="::historyMessage.media ? true : false" class="im_message_media" ng-switch="historyMessage.media._"> <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="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="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="messageMediaAudio" class="im_message_audio" my-audio-player audio="historyMessage.media.audio"></div>
<div ng-switch-when="messageMediaGeo" my-message-map></div> <div ng-switch-when="messageMediaGeo" my-message-map></div>

2
app/partials/desktop/message_attach_document.html

@ -32,7 +32,7 @@
<a ng-switch-default href="" ng-click="docSave()" my-i18n="message_attach_document_download"></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> <a ng-if="::document.withPreview" href="" ng-click="docOpen()" my-i18n="message_attach_document_open"></a>
</div> </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> <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="im_message_download_progress_wrap">
<div class="progress tg_down_progress"> <div class="progress tg_down_progress">

8
app/partials/desktop/message_attach_pending.html

@ -1,14 +1,16 @@
<div class="im_message_document im_message_upload_file" ng-class="::'im_message_upload_' + historyMessage.media.type"> <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_info">
<div class="im_message_document_name_wrap"> <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_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> <span class="im_message_document_size" ng-if="historyMessage.media.progress" ng-bind="historyMessage.media.progress | formatSizeProgress"></span>
</div> </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> <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="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 class="progress-bar progress-bar-success" role="progressbar" ng-style="{width: historyMessage.media.progress.percent + '%'}"></div>
</div> </div>
</div> </div>

25
app/partials/desktop/message_attach_video.html

@ -1,29 +1,32 @@
<div class="im_message_video im_message_document_thumbed"> <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'}"> <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="::historyMessage.media.video.duration | duration"></span> <span class="im_message_video_duration" ng-bind="::video.duration | duration"></span>
<i class="icon icon-videoplay"></i> <i class="icon icon-videoplay"></i>
<img <img
class="im_message_video_thumb" class="im_message_video_thumb"
my-load-thumb my-load-thumb
thumb="historyMessage.media.video.thumb" thumb="video.thumb"
/> />
</a> </a>
<div class="im_message_document_info"> <div class="im_message_document_info">
<div class="im_message_document_name_wrap"> <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_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="!video.progress.enabled" ng-bind="::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.progress | formatSizeProgress"></span>
</div> </div>
<div class="im_message_document_actions" ng-if="!historyMessage.media.video.progress.enabled"> <div class="im_message_document_actions" ng-if="!video.progress.enabled">
<a href="" ng-click="downloadVideo(historyMessage.media.video.id)" my-i18n="message_attach_video_download"></a> <a href="" ng-click="videoSave()" ng-switch="video.downloaded">
<a href="" ng-click="openVideo(historyMessage.media.video.id, historyMessage.id)" my-i18n="message_attach_video_play"></a> <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>
<div class="clearfix cancelable_progress_wrap" ng-if="historyMessage.media.video.progress.enabled"> <div class="clearfix im_message_cancelable_progress_wrap" ng-if="video.progress.enabled">
<a class="im_message_media_progress_cancel pull-right" ng-click="historyMessage.media.video.progress.cancel()" my-i18n="modal_cancel"></a> <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="im_message_download_progress_wrap">
<div class="progress tg_down_progress"> <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> </div>
</div> </div>

2
app/partials/desktop/settings_modal.html

@ -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>
<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>
</div> </div>

6
app/partials/mobile/full_gif.html

@ -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-when="true" class="img_gif_image" ng-src="{{document.url}}" />
<img ng-switch-default class="img_gif_thumb" my-load-thumb thumb="document.thumb" /> <img ng-switch-default class="img_gif_thumb" my-load-thumb thumb="document.thumb" />
@ -17,7 +17,7 @@
<div ng-switch-default class="img_gif_info_wrap"> <div ng-switch-default class="img_gif_info_wrap">
<div class="img_gif_label pull-left">GIF</div> <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>
</div> </div>

14
app/partials/mobile/full_video.html

@ -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_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_wrap" ng-style="{width: video.full.width + 'px', height: video.full.height + 'px'}">
<div class="img_fullsize_progress progress tg_progress"> <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>
</div> </div>
<div class="img_fullsize_wrap" ng-if="!player.src"> <div class="img_fullsize_wrap" ng-if="!video.url">
<img <img
class="img_fullsize" class="img_fullsize"
my-load-thumb my-load-thumb
thumb="video.fullThumb" thumb="video.fullThumb"
/> />
</div> </div>
<div class="video_full_player" ng-if="player.src"> <div class="video_full_player" ng-if="video.url" ng-switch="player.quicktime">
<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"/> <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 width="{{video.full.width}}" height="{{video.full.height}}" controls autoplay ng-if="!player.quicktime"> <video ng-switch-default width="{{video.full.width}}" height="{{video.full.height}}" controls autoplay >
<source ng-src="{{player.src}}" type="video/mp4"> <source ng-src="{{video.url}}" type="video/mp4">
</video> </video>
</div> </div>
<div class="video_full_error_wrap" ng-if="error"> <div class="video_full_error_wrap" ng-if="error">

2
app/partials/mobile/message.html

@ -41,7 +41,7 @@
<div ng-if="::historyMessage.media || false" class="im_message_media" ng-switch="historyMessage.media._"> <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="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="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="messageMediaAudio" class="im_message_audio" my-audio-player audio="historyMessage.media.audio"></div>
<div ng-switch-when="messageMediaGeo" my-message-map></div> <div ng-switch-when="messageMediaGeo" my-message-map></div>

37
app/partials/mobile/message_attach_document.html

@ -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 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>
<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}"> <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="icon icon-document" ng-if="::!historyMessage.media.document.thumb"></i> <i class="im_message_file_button_icon"></i>
<div class="im_message_document_thumb_wrap" ng-if="::historyMessage.media.document.thumb"> </a>
<a ng-if="::document.thumb" ng-click="docOpen()">
<div class="im_message_document_thumb_wrap">
<img <img
class="im_message_document_thumb" class="im_message_document_thumb"
my-load-thumb my-load-thumb
thumb="historyMessage.media.document.thumb" thumb="document.thumb"
/> />
</div> </div>
</a> </a>
<div class="im_message_document_info"> <div class="im_message_document_info">
<div class="im_message_document_name_wrap"> <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_name" ng-bind="::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="!document.progress.enabled" ng-bind="::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_size" ng-if="document.progress.enabled" ng-bind="document.progress | formatSizeProgress"></span>
</div> </div>
<div class="im_message_document_actions" ng-if="!historyMessage.media.document.progress.enabled"> <div class="im_message_document_actions" ng-if="!document.progress.enabled" ng-switch="document.downloaded">
<a href="" ng-click="downloadDoc(historyMessage.media.document.id)" my-i18n="message_attach_document_download"></a> <a ng-switch-when="true" href="" ng-click="docSave()" my-i18n="message_attach_document_save"></a>
<a href="" ng-click="downloadDoc(historyMessage.media.document.id, 1)" ng-if="::historyMessage.media.document.withPreview" my-i18n="message_attach_document_open"></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>
<div class="clearfix cancelable_progress_wrap" ng-if="historyMessage.media.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="historyMessage.media.document.progress.cancel()" my-i18n="modal_cancel"></a> <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="im_message_download_progress_wrap">
<div class="progress tg_down_progress"> <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> </div>
</div> </div>

2
app/partials/mobile/message_attach_pending.html

@ -5,7 +5,7 @@
<span class="im_message_document_name" ng-bind="::historyMessage.media.file_name"></span> <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> <span class="im_message_document_size" ng-if="historyMessage.media.progress" ng-bind="historyMessage.media.progress | formatSizeProgress"></span>
</div> </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> <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="im_message_download_progress_wrap">
<div class="progress tg_down_progress"> <div class="progress tg_down_progress">

6
app/partials/mobile/message_attach_video.html

@ -1,11 +1,11 @@
<div class="im_message_video im_message_document_thumbed"> <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'}"> <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="::historyMessage.media.video.duration | duration"></span> <span class="im_message_video_duration" ng-bind="::video.duration | duration"></span>
<i class="icon icon-videoplay"></i> <i class="icon icon-videoplay"></i>
<img <img
class="im_message_video_thumb" class="im_message_video_thumb"
my-load-thumb my-load-thumb
thumb="historyMessage.media.video.thumb" thumb="video.thumb"
/> />
</a> </a>
</div> </div>

2
app/partials/mobile/photo_modal.html

@ -12,7 +12,7 @@
</div> </div>
<p class="media_modal_info"> <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> </p>
</div> </div>

1
app/partials/mobile/slider.html

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

2
app/partials/mobile/video_modal.html

@ -12,7 +12,7 @@
</div> </div>
<p class="media_modal_info"> <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> </p>
</div> </div>

Loading…
Cancel
Save