Add ability to hide embedded media

Embedded media like images and video can now individually be collapsed

A new preference "Collapse media by default" is also added, the default
is to not collapse media.

Since images are not always shown, "showImage" is also renamed to
"loadImage"

Closes #1187
pull/2763/head
Dennis Brakhane 10 years ago committed by Dennis Brakhane
parent ec9aa61ee3
commit 1480d7be91
  1. 3
      packages/rocketchat-lib/i18n/de.i18n.json
  2. 1
      packages/rocketchat-lib/i18n/en.i18n.json
  3. 8
      packages/rocketchat-message-attachments/client/messageAttachment.coffee
  4. 51
      packages/rocketchat-message-attachments/client/messageAttachment.html
  5. 7
      packages/rocketchat-oembed/client/oembedAudioWidget.coffee
  6. 17
      packages/rocketchat-oembed/client/oembedAudioWidget.html
  7. 7
      packages/rocketchat-oembed/client/oembedFrameWidget.coffee
  8. 39
      packages/rocketchat-oembed/client/oembedFrameWidget.html
  9. 9
      packages/rocketchat-oembed/client/oembedImageWidget.coffee
  10. 35
      packages/rocketchat-oembed/client/oembedImageWidget.html
  11. 6
      packages/rocketchat-oembed/client/oembedUrlWidget.coffee
  12. 6
      packages/rocketchat-oembed/client/oembedVideoWidget.coffee
  13. 15
      packages/rocketchat-oembed/client/oembedVideoWidget.html
  14. 7
      packages/rocketchat-oembed/client/oembedYoutubeWidget.coffee
  15. 13
      packages/rocketchat-oembed/client/oembedYoutubeWidget.html
  16. 3
      packages/rocketchat-oembed/package.js
  17. 11
      packages/rocketchat-spotify/lib/client/oembedSpotifyWidget.html
  18. 17
      packages/rocketchat-theme/assets/stylesheets/base.less
  19. 1
      packages/rocketchat-ui-account/account/accountPreferences.coffee
  20. 7
      packages/rocketchat-ui-account/account/accountPreferences.html
  21. 8
      packages/rocketchat-ui/views/app/room.coffee
  22. 3
      server/methods/saveUserPreferences.coffee

@ -183,6 +183,7 @@
"Client_Secret" : "Client-Secret",
"close" : "Schließen",
"Closed" : "Geschlossen",
"Collapse_Embedded_Media_By_Default": "Eingebettete Medien standardmäßig ausblenden",
"coming_soon" : "kommt bald",
"Commands" : "Befehle",
"Compact_View" : "Kompaktansicht",
@ -1017,4 +1018,4 @@
"Your_Open_Source_solution" : "Deine eigene Open-Source-Chat-Lösung.",
"Your_password_is_wrong" : "Falsches Passwort",
"Your_push_was_sent_to_s_devices" : "Die Push-Nachricht wurde an %s Geräte gesendet."
}
}

@ -189,6 +189,7 @@
"Clients_will_refresh_in_a_few_seconds" : "Clients will refresh in a few seconds",
"close" : "close",
"Closed" : "Closed",
"Collapse_Embedded_Media_By_Default": "Collapse embedded media by default",
"coming_soon" : "coming soon",
"Commands" : "Commands",
"Compact_View" : "Compact View",

@ -13,7 +13,7 @@ Template.messageAttachment.helpers
parsedText: ->
renderMessageBody { msg: this.text }
showImage: ->
loadImage: ->
if Meteor.user()?.settings?.preferences?.autoImageLoad is false and this.downloadImages? is not true
return false
@ -31,3 +31,9 @@ Template.messageAttachment.helpers
when 'warning' then return '#FCB316'
when 'danger' then return '#D30230'
else return @color
collapsed: ->
if this.collapsed?
return this.collapsed
else
return Meteor.user()?.settings?.preferences?.collapseMediaByDefault is true

@ -22,20 +22,23 @@
</div>
{{/if}}
{{/if}}
{{#if title}}
{{#if title_link}}
<div class="attachment-title">
<div class="attachment-title">
{{#if title_link}}
<a href="{{fixCordova title_link}}" target="_blank">{{title}}</a>
{{#if title_link_download}}
<a class="icon-download attachment-download-icon" href="{{fixCordova title_link}}" target="_blank" download=""></a>
{{/if}}
</div>
{{else}}
<div class="attachment-title">{{title}}</div>
{{title}}
{{/if}}
{{#if collapsed}}
<span class="collapse-switch icon-right-dir" data-url="{{image_url}}" data-collapsed="{{collapsed}}"></span>
{{else}}
<span class="collapse-switch icon-down-dir" data-url="{{image_url}}" data-collapsed="{{collapsed}}"></span>
{{/if}}
</div>
{{/if}}
<div class="attachment-flex">
{{#if thumb_url}}
<div class="attachment-thumb">
@ -51,8 +54,9 @@
</div>
{{#if image_url}}
<div class="attachment-image">
{{#if showImage}}
{{#unless collapsed}}
<div class="attachment-image">
{{#if loadImage}}
<a href="{{fixCordova image_url}}" class="swipebox" target="_blank">
<div class="inline-image" style="background-image: url('{{fixCordova image_url}}');">
<img src="{{fixCordova image_url}}" height="{{getImageHeight image_dimensions.height}}">
@ -64,25 +68,30 @@
<div>click to load</div>
</div>
{{/if}}
</div>
</div>
{{/unless}}
{{/if}}
{{#if audio_url}}
<div class="attachment-audio">
<audio controls>
<source src="{{fixCordova audio_url}}" type="{{audio_type}}">
Your browser does not support the audio element.
</audio>
</div>
{{#unless collapsed}}
<div class="attachment-audio">
<audio controls>
<source src="{{fixCordova audio_url}}" type="{{audio_type}}">
Your browser does not support the audio element.
</audio>
</div>
{{/unless}}
{{/if}}
{{#if video_url}}
<div class="attachment-video">
<video controls class="inline-video">
<source src="{{fixCordova video_url}}" type="{{video_type}}">
Your browser does not support the video element.
</video>
</div>
{{#unless collapsed}}
<div class="attachment-video">
<video controls class="inline-video">
<source src="{{fixCordova video_url}}" type="{{video_type}}">
Your browser does not support the video element.
</video>
</div>
{{/unless}}
{{/if}}
{{#if fields}}

@ -0,0 +1,7 @@
Template.oembedAudioWidget.helpers
collapsed: ->
if this.collapsed?
return this.collapsed
else
return Meteor.user()?.settings?.preferences?.collapseMediaByDefault is true

@ -1,12 +1,17 @@
<template name="oembedAudioWidget">
<a href="{{url}}" target="_blank">
{{#if parsedUrl}}
<blockquote>
<audio controls>
<source src="{{url}}" type="{{headers.contentType}}">
Your browser does not support the audio element.
</audio>
</blockquote>
{{#if collapsed}}
<span class="collapse-switch icon-right-dir" data-url="{{url}}" data-collapsed="{{collapsed}}"></span>
{{else}}
<span class="collapse-switch icon-down-dir" data-url="{{url}}" data-collapsed="{{collapsed}}"></span>
<blockquote>
<audio controls>
<source src="{{url}}" type="{{headers.contentType}}">
Your browser does not support the audio element.
</audio>
</blockquote>
{{/if}}
{{/if}}
</a>
</template>

@ -0,0 +1,7 @@
Template.oembedFrameWidget.helpers
collapsed: ->
if this.collapsed?
return this.collapsed
else
return Meteor.user()?.settings?.preferences?.collapseMediaByDefault is true

@ -1,25 +1,32 @@
<template name="oembedFrameWidget">
{{#if parsedUrl}}
<blockquote>
{{#if meta.oembedProviderName}}
{{#if meta.oembedProviderUrl}}
<a href="{{meta.oembedProviderUrl}}" style="color: #9e9ea6">{{meta.oembedProviderName}}</a><br/>
{{/if}}
{{#if parsedUrl}}
<blockquote>
{{#if meta.oembedProviderName}}
{{#if meta.oembedProviderUrl}}
<a href="{{meta.oembedProviderUrl}}" style="color: #9e9ea6">{{meta.oembedProviderName}}</a>
{{/if}}
{{#if meta.oembedAuthorName}}
{{#if meta.oembedAuthorUrl}}
<a href="{{meta.oembedAuthorUrl}}">{{meta.oembedAuthorName}}</a><br/>
{{/if}}
{{/if}}
{{#if meta.oembedAuthorName}}
{{#if meta.oembedAuthorUrl}}
<br class="only-after-a"/>
<a href="{{meta.oembedAuthorUrl}}">{{meta.oembedAuthorName}}</a>
{{/if}}
{{#if meta.oembedTitle}}
{{#if meta.oembedUrl}}
<a href="{{meta.oembedUrl}}">{{meta.oembedTitle}}</a><br/>
{{/if}}
{{/if}}
{{#if meta.oembedTitle}}
{{#if meta.oembedUrl}}
<br class="only-after-a"/>
<a href="{{meta.oembedUrl}}">{{meta.oembedTitle}}</a>
{{/if}}
{{/if}}
{{#if collapsed}}
<span class="collapse-switch icon-right-dir" data-url="{{url}}" data-collapsed="{{collapsed}}"></span><br/>
{{else}}
<span class="collapse-switch icon-down-dir" data-url="{{url}}" data-collapsed="{{collapsed}}"></span><br/>
{{#if meta.oembedDescription}}
<p>{{meta.oembedDescription}}</p>
{{/if}}
{{{meta.oembedHtml}}}
</blockquote>
{{/if}}
{{/if}}
</blockquote>
{{/if}}
</template>

@ -1,5 +1,5 @@
Template.oembedImageWidget.helpers
showImage: ->
loadImage: ->
if Meteor.user()?.settings?.preferences?.autoImageLoad is false and this.downloadImages? is not true
return false
@ -8,3 +8,10 @@ Template.oembedImageWidget.helpers
return false
return true
collapsed: ->
if this.collapsed?
return this.collapsed
else
return Meteor.user()?.settings?.preferences?.collapseMediaByDefault is true

@ -1,20 +1,23 @@
<template name="oembedImageWidget">
{{#if showImage}}
{{#if parsedUrl}}
<div>
<a href="{{url}}" class="swipebox" target="_blank">
<div class="inline-image" style="background-image: url('{{url}}');">
<img src="{{url}}" height="200">
</div>
</a>
</div>
{{/if}}
{{else}}
{{#if parsedUrl}}
<div class="image-to-download" data-url="{{url}}">
<i class="icon-picture"></i>
<div>click to load</div>
</div>
{{#if parsedUrl}}
{{#if collapsed}}
<span class="collapse-switch icon-right-dir" data-url="{{url}}" data-collapsed="{{collapsed}}"></span>
{{else}}
<span class="collapse-switch icon-down-dir" data-url="{{url}}" data-collapsed="{{collapsed}}"></span>
{{#if loadImage}}
<div>
<a href="{{url}}" class="swipebox" target="_blank">
<div class="inline-image" style="background-image: url('{{url}}');">
<img src="{{url}}" height="200">
</div>
</a>
</div>
{{else}}
<div class="image-to-download" data-url="{{url}}">
<i class="icon-picture"></i>
<div>click to load</div>
</div>
{{/if}}
{{/if}}
{{/if}}
</template>

@ -34,3 +34,9 @@ Template.oembedUrlWidget.helpers
show: ->
return getDescription(this)? or getTitle(this)?
collapsed: ->
if this.collapsed?
return this.collapsed
else
return Meteor.user()?.settings?.preferences?.collapseMediaByDefault is true

@ -14,3 +14,9 @@ Template.oembedVideoWidget.helpers
title: ->
return getTitle @
collapsed: ->
if this.collapsed?
return this.collapsed
else
return Meteor.user()?.settings?.preferences?.collapseMediaByDefault is true

@ -2,11 +2,16 @@
{{#if parsedUrl}}
<blockquote>
<div><a href="{{url}}">{{parsedUrl.host}}</a></div>
<div>{{title}}</div>
<video controls class="inline-video">
<source src="{{url}}" type="{{contentType}}">
Your browser does not support the video element.
</video>
<span>{{title}}</span>
{{#if collapsed}}
<span class="collapse-switch icon-right-dir" data-url="{{url}}" data-collapsed="{{collapsed}}"></span>
{{else}}
<span class="collapse-switch icon-down-dir" data-url="{{url}}" data-collapsed="{{collapsed}}"></span><br/>
<video controls class="inline-video">
<source src="{{url}}" type="{{contentType}}">
Your browser does not support the video element.
</video>
{{/if}}
</blockquote>
{{/if}}
</template>

@ -0,0 +1,7 @@
Template.oembedYoutubeWidget.helpers
collapsed: ->
if this.collapsed?
return this.collapsed
else
return Meteor.user()?.settings?.preferences?.collapseMediaByDefault is true

@ -1,9 +1,14 @@
<template name="oembedYoutubeWidget">
{{#if parsedUrl}}
<blockquote>
<a href="{{url}}">{{parsedUrl.host}}</a><br>
<iframe width="355" height="200" src="{{meta.twitterPlayer}}" frameborder="0" allowfullscreen></iframe><br>
{{{meta.description}}}
<a href="{{url}}">{{parsedUrl.host}}</a>
{{#if collapsed}}
<span class="collapse-switch icon-right-dir" data-url="{{url}}" data-collapsed="{{collapsed}}"></span><br>
{{else}}
<span class="collapse-switch icon-down-dir" data-url="{{url}}" data-collapsed="{{collapsed}}"></span><br>
<iframe width="355" height="200" src="{{meta.twitterPlayer}}" frameborder="0" allowfullscreen></iframe><br>
{{{meta.description}}}
{{/if}}
</blockquote>
{{/if}}
</template>
</template>

@ -28,16 +28,19 @@ Package.onUse(function(api) {
api.addFiles('client/oembedImageWidget.coffee', 'client');
api.addFiles('client/oembedAudioWidget.html', 'client');
api.addFiles('client/oembedAudioWidget.coffee', 'client');
api.addFiles('client/oembedVideoWidget.html', 'client');
api.addFiles('client/oembedVideoWidget.coffee', 'client');
api.addFiles('client/oembedYoutubeWidget.html', 'client');
api.addFiles('client/oembedYoutubeWidget.coffee', 'client');
api.addFiles('client/oembedUrlWidget.html', 'client');
api.addFiles('client/oembedUrlWidget.coffee', 'client');
api.addFiles('client/oembedFrameWidget.html', 'client');
api.addFiles('client/oembedFrameWidget.coffee', 'client');
api.addFiles('server/server.coffee', 'server');
api.addFiles('server/providers.coffee', 'server');

@ -3,11 +3,16 @@
<blockquote>
<a href="https://www.spotify.com" style="color: #9e9ea6">Spotify</a><br/>
{{#if match meta.ogAudio "spotify:artist:\\S+"}}
<a href="{{url}}">{{{meta.ogTitle}}}</a><br/>
<a href="{{url}}">{{{meta.ogTitle}}}</a>
{{else}}
<a href="{{url}}">{{{replace meta.ogDescription ", an? (?:song|album) by (.+?) on Spotify" " - $1" regex=true}}}</a><br/>
<a href="{{url}}">{{{replace meta.ogDescription ", an? (?:song|album) by (.+?) on Spotify" " - $1" regex=true}}}</a>
{{/if}}
{{#if collapsed}}
<span class="collapse-switch icon-right-dir" data-url="{{url}}" data-collapsed="{{collapsed}}"></span>
{{else}}
<span class="collapse-switch icon-down-dir" data-url="{{url}}" data-collapsed="{{collapsed}}"></span>
<iframe width="300" height="380" src="https://embed.spotify.com/?uri={{meta.ogAudio}}" frameborder="0"></iframe><br/>
{{/if}}
<iframe width="300" height="380" src="https://embed.spotify.com/?uri={{meta.ogAudio}}" frameborder="0"></iframe><br/>
</blockquote>
{{/if}}
</template>

@ -2817,8 +2817,8 @@ a.github-fork {
}
// .message-dropdown {
// top: 100%;
// left: 0;
// top: 100%;
// left: 0;
// }
&:hover {
@ -4765,3 +4765,16 @@ body:not(.is-cordova) {
top: -5px;
opacity: .6;
}
.collapse-switch {
cursor: pointer;
}
// kinda hacky, needed in oembedFrageWidget.html
br.only-after-a {
display: none;
}
a + br.only-after-a {
display: block;
}

@ -67,6 +67,7 @@ Template.accountPreferences.onCreated ->
data.useEmojis = $('input[name=useEmojis]:checked').val()
data.convertAsciiEmoji = $('input[name=convertAsciiEmoji]:checked').val()
data.saveMobileBandwidth = $('input[name=saveMobileBandwidth]:checked').val()
data.collapseMediaByDefault = $('input[name=collapseMediaByDefault]:checked').val()
data.compactView = $('input[name=compactView]:checked').val()
data.unreadRoomsMode = $('input[name=unreadRoomsMode]:checked').val()
data.autoImageLoad = $('input[name=autoImageLoad]:checked').val()

@ -70,6 +70,13 @@
<label><input type="radio" name="saveMobileBandwidth" value="0" checked="{{checked 'saveMobileBandwidth' false}}" /> {{_ "False"}}</label>
</div>
</div>
<div class="input-line double-col" id="collapseMediaByDefault">
<label>{{_ "Collapse_Embedded_Media_By_Default"}}</label>
<div>
<label><input type="radio" name="collapseMediaByDefault" value="1" checked="{{checked 'collapseMediaByDefault' true}}" /> {{_ "True"}}</label>
<label><input type="radio" name="collapseMediaByDefault" value="0" checked="{{checked 'collapseMediaByDefault' false true}}" /> {{_ "False"}}</label>
</div>
</div>
<div class="input-line double-col" id="compactView">
<label>{{_ "Compact_View"}}</label>
<div>

@ -418,6 +418,14 @@ Template.room.events
ChatMessage.update {_id: this._arguments[1]._id, 'urls.url': $(event.currentTarget).data('url')}, {$set: {'urls.$.downloadImages': true}}
ChatMessage.update {_id: this._arguments[1]._id, 'attachments.image_url': $(event.currentTarget).data('url')}, {$set: {'attachments.$.downloadImages': true}}
'click .collapse-switch': (e) ->
url = $(e.currentTarget).data('url')
collapsed = $(e.currentTarget).data('collapsed')
id = @_arguments[1]._id
ChatMessage.update {_id: id, 'urls.url': url}, {$set: {'urls.$.collapsed': !collapsed}}
for type in ['image_url', 'audio_url', 'video_url']
ChatMessage.update {_id: id, "attachments.#{type}": url}, {$set: {'attachments.$.collapsed': !collapsed}}
'dragenter .dropzone': (e) ->
e.currentTarget.classList.add 'over'

@ -21,6 +21,9 @@ Meteor.methods
if settings.saveMobileBandwidth?
preferences.saveMobileBandwidth = if settings.saveMobileBandwidth is "1" then true else false
if settings.collapseMediaByDefault?
preferences.collapseMediaByDefault = if settings.collapseMediaByDefault is "1" then true else false
if settings.compactView?
preferences.compactView = if settings.compactView is "1" then true else false

Loading…
Cancel
Save