Skip to content

Commit

Permalink
Merge pull request RocketChat#270 from Shailesh351/sb_pwa_8_wc
Browse files Browse the repository at this point in the history
[Upstream PWA] RocketChat#17649 Add Share Functionality
  • Loading branch information
ear-dev authored May 14, 2020
2 parents c670e54 + 019b89a commit 39efc0e
Show file tree
Hide file tree
Showing 13 changed files with 283 additions and 1 deletion.
22 changes: 21 additions & 1 deletion app/lib/client/defaultTabBars.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Session } from 'meteor/session';

import { TabBar } from '../../ui-utils';
import { TabBar, popover } from '../../ui-utils';
import { share, isShareAvailable } from '../../utils';
import { Rooms } from '../../models';
import { hasAllPermission } from '../../authorization';
import { roomTypes } from '../../utils/client';
Expand Down Expand Up @@ -86,3 +87,22 @@ TabBar.addButton({
template: 'keyboardShortcuts',
order: 99,
});

// Add Share button in Room
const shareButton = {
groups: ['channel', 'group', 'direct'],
id: 'share',
i18nTitle: 'Share',
icon: 'share',
template: 'share',
order: 500,
};

if (isShareAvailable()) {
shareButton.action = () => {
share();
popover.close();
};
}

TabBar.addButton(shareButton);
56 changes: 56 additions & 0 deletions app/theme/client/imports/components/share.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
.share-header-container {
display: flex;
flex-wrap: wrap;
}

.share-icon {
display: inline-block;

box-sizing: border-box;

width: 25%;
min-width: 46px;

padding: 16px 0;

cursor: pointer;

text-align: center;

border: none;

background-color: transparent;

box-shadow: inset 0 0 20px rgba(0, 0, 0, 0);

font-size: 12px;
font-weight: 400;

-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;

&:hover {
box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.125);
}
}

.share-svg-icon {
display: block;

width: 42px;
height: 36px;
margin: auto;

&__header {
width: 24px;
height: 24px;
}
}

.share-icon-title {
display: block;

padding-top: 10px;

font-size: 14px;
}
1 change: 1 addition & 0 deletions app/theme/client/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
@import 'imports/components/emojiPicker.css';
@import 'imports/components/table.css';
@import 'imports/components/tabs.css';
@import 'imports/components/share.css';

/* Modal */
@import 'imports/components/modal/full-modal.css';
Expand Down
Empty file added app/ui-share/README.md
Empty file.
2 changes: 2 additions & 0 deletions app/ui-share/client/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import './share.html';
import './share';
45 changes: 45 additions & 0 deletions app/ui-share/client/share.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<template name="share">
<div class="rc-popover__column">
<div class="share-header-container">
<button class="share-icon" data-type="copy">
<svg class="share-svg-icon__header" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="#424242" d="M320 448v40c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V120c0-13.255 10.745-24 24-24h72v296c0 30.879 25.121 56 56 56h168zm0-344V0H152c-13.255 0-24 10.745-24 24v368c0 13.255 10.745 24 24 24h272c13.255 0 24-10.745 24-24V128H344c-13.2 0-24-10.8-24-24zm120.971-31.029L375.029 7.029A24 24 0 0 0 358.059 0H352v96h96v-6.059a24 24 0 0 0-7.029-16.97z"></path></svg>
<span class="share-icon-title">Copy</span>
</button>
<button class="share-icon" data-type="print">
<svg class="share-svg-icon__header" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#424242" d="M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
<span class="share-icon-title">Print</span>
</button>
<button class="share-icon" data-type="email">
<svg class="share-svg-icon__header" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path fill="#424242" d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 14H4V8l8 5 8-5v10zm-8-7L4 6h16l-8 5z"/></svg>
<span class="share-icon-title">Email</span>
</button>
<button class="share-icon" data-type="sms">
<svg class="share-svg-icon__header" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#424242" d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM9 11H7V9h2v2zm4 0h-2V9h2v2zm4 0h-2V9h2v2z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
<span class="share-icon-title">SMS</span>
</button>
</div>

<div class="share-header-container">
<button class="share-icon" data-type="facebook">
<svg class="share-svg-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="#3b5998" d="M448 56.7v398.5c0 13.7-11.1 24.7-24.7 24.7H309.1V306.5h58.2l8.7-67.6h-67v-43.2c0-19.6 5.4-32.9 33.5-32.9h35.8v-60.5c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87 89.4v49.9h-58.4v67.6h58.4V480H24.7C11.1 480 0 468.9 0 455.3V56.7C0 43.1 11.1 32 24.7 32h398.5c13.7 0 24.8 11.1 24.8 24.7z"></path></svg>
<span class="share-icon-title">Facebook</span>
</button>
<button class="share-icon" data-type="whatsapp">
<svg class="share-svg-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="#075e54" d="M224 122.8c-72.7 0-131.8 59.1-131.9 131.8 0 24.9 7 49.2 20.2 70.1l3.1 5-13.3 48.6 49.9-13.1 4.8 2.9c20.2 12 43.4 18.4 67.1 18.4h.1c72.6 0 133.3-59.1 133.3-131.8 0-35.2-15.2-68.3-40.1-93.2-25-25-58-38.7-93.2-38.7zm77.5 188.4c-3.3 9.3-19.1 17.7-26.7 18.8-12.6 1.9-22.4.9-47.5-9.9-39.7-17.2-65.7-57.2-67.7-59.8-2-2.6-16.2-21.5-16.2-41s10.2-29.1 13.9-33.1c3.6-4 7.9-5 10.6-5 2.6 0 5.3 0 7.6.1 2.4.1 5.7-.9 8.9 6.8 3.3 7.9 11.2 27.4 12.2 29.4s1.7 4.3.3 6.9c-7.6 15.2-15.7 14.6-11.6 21.6 15.3 26.3 30.6 35.4 53.9 47.1 4 2 6.3 1.7 8.6-1 2.3-2.6 9.9-11.6 12.5-15.5 2.6-4 5.3-3.3 8.9-2 3.6 1.3 23.1 10.9 27.1 12.9s6.6 3 7.6 4.6c.9 1.9.9 9.9-2.4 19.1zM400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM223.9 413.2c-26.6 0-52.7-6.7-75.8-19.3L64 416l22.5-82.2c-13.9-24-21.2-51.3-21.2-79.3C65.4 167.1 136.5 96 223.9 96c42.4 0 82.2 16.5 112.2 46.5 29.9 30 47.9 69.8 47.9 112.2 0 87.4-72.7 158.5-160.1 158.5z"></path></svg>
<span class="share-icon-title">WhatsApp</span>
</button>
<button class="share-icon" data-type="twitter">
<svg class="share-svg-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="#1da1f2" d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"></path></svg>
<span class="share-icon-title">Twitter</span>
</button>
<button class="share-icon" data-type="linkedin">
<svg class="share-svg-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="#0077b5" d="M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"></path></svg>
<span class="share-icon-title">LinkedIn</span>
</button>
<button class="share-icon" data-type="telegram">
<svg class="share-svg-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path fill="#0088cc" d="M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm121.8 169.9l-40.7 191.8c-3 13.6-11.1 16.9-22.4 10.5l-62-45.7-29.9 28.8c-3.3 3.3-6.1 6.1-12.5 6.1l4.4-63.1 114.9-103.8c5-4.4-1.1-6.9-7.7-2.5l-142 89.4-61.2-19.1c-13.3-4.2-13.6-13.3 2.8-19.7l239.1-92.2c11.1-4 20.8 2.7 17.2 19.5z"></path></svg>
<span class="share-icon-title">Telegram</span>
</button>
</div>
</div>
</template>
71 changes: 71 additions & 0 deletions app/ui-share/client/share.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { Template } from 'meteor/templating';

import { getShareData } from '../../utils';

function getShareString() {
const data = getShareData();
return `${ data.title } \n${ data.url } \n${ data.text }`;
}

function fallbackCopyTextToClipboard(text) {
const textArea = document.createElement('textarea');
textArea.value = text;
textArea.style.position = 'fixed'; // avoid scrolling to bottom
document.body.appendChild(textArea);
textArea.focus();
textArea.select();

try {
document.execCommand('copy');
} catch (err) {
console.error('Unable to copy', err);
}

document.body.removeChild(textArea);
}

Template.share.helpers({

});

Template.share.events({
'click [data-type="copy"]'() {
if (!navigator.clipboard) {
fallbackCopyTextToClipboard(getShareString());
return;
}
navigator.clipboard.writeText(getShareString());
},
'click [data-type="print"]'() {
self.print();
},
'click [data-type="email"]'() {
const { title } = getShareData();
window.open(`mailto:?subject=${ title }&body=${ getShareString() }`);
},
'click [data-type="sms"]'() {
location.href = `sms:?&body=${ getShareString() }`;
},


'click [data-type="facebook"]'() {
const { url } = getShareData();
window.open(`https://www.facebook.com/sharer/sharer.php?u=${ encodeURIComponent(url) }`);
},
'click [data-type="whatsapp"]'() {
window.open(`https://api.whatsapp.com/send?text=${ encodeURIComponent(getShareString()) }`);
},
'click [data-type="twitter"]'() {
const { url } = getShareData();
window.open(`http://twitter.com/share?text=${ getShareString() }&url=${ url }`);
},
'click [data-type="linkedin"]'() {
const { title, url } = getShareData();
window.open(`https://www.linkedin.com/shareArticle?mini=true&url=${ url }&title=${ title }&summary=${ getShareString() }&source=LinkedIn`);
},
'click [data-type="telegram"]'() {
const { url } = getShareData();
window.open(`https://telegram.me/share/msg?url=${ url }&text=${ getShareString() }`);
},

});
1 change: 1 addition & 0 deletions app/ui-share/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './client/index';
7 changes: 7 additions & 0 deletions app/ui-sidenav/client/sidebarHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,12 @@ const toolbarButtons = (/* user */) => [{
};
}

const shareOption = {
name: t('Share'),
icon: 'share',
type: 'share-action',
};

const sortOption = {
name: t('Sort'),
icon: 'sort',
Expand Down Expand Up @@ -251,6 +257,7 @@ const toolbarButtons = (/* user */) => [{
if (isMobile()) {
config.columns[0].groups[0].items = config.columns[0].groups[0].items.concat([sortOption, directoryOption]);
}
config.columns[0].groups[0].items = config.columns[0].groups[0].items.concat([shareOption]);
popover.open(config);
},
}];
Expand Down
18 changes: 18 additions & 0 deletions app/ui-utils/client/lib/popover.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { FlowRouter } from 'meteor/kadira:flow-router';
import { Template } from 'meteor/templating';
import _ from 'underscore';

import { share, isShareAvailable } from '../../../utils';
import { hide, leave } from './ChannelActions';
import { messageBox } from './messageBox';
import { MessageAction } from './MessageAction';
Expand Down Expand Up @@ -191,6 +192,23 @@ Template.popover.events({
};
popover.open(config);
},
'click [data-type="share-action"]'(e) {
if (isShareAvailable()) {
share();
} else {
popover.close();
const options = [];
const config = {
template: 'share',
currentTarget: e.target,
data: {
options,
},
offsetVertical: e.target.clientHeight + 10,
};
popover.open(config);
}
},
'click [data-type="sidebar-item"]'(e, instance) {
popover.close();
const { rid, name, template } = instance.data.data;
Expand Down
1 change: 1 addition & 0 deletions app/utils/client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ export { APIClient, mountArrayQueryParameters } from './lib/RestApiClient';
export { canDeleteMessage } from './lib/canDeleteMessage';
export { mime } from '../lib/mimeTypes';
export { secondsToHHMMSS } from '../lib/timeConverter';
export { share, isShareAvailable, getShareData } from './lib/share';
export { isMobile } from './lib/isMobile';
59 changes: 59 additions & 0 deletions app/utils/client/lib/share.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { Meteor } from 'meteor/meteor';

import { settings } from '../../../settings';


export const isShareAvailable = () => {
if (navigator.share) { return true; }
return false;
};

export const getShareData = () => {
const data = {};

const siteName = settings.get('Site_Name') || '';
const siteURL = settings.get('Site_Url') || '';

data.url = document.location.href || siteURL;
const path = new URL(data.url).pathname;
const roomName = path.substring(path.lastIndexOf('/') + 1);

const templateText = `${ siteName } is open source team communication app.`;

data.title = `${ siteName }`;
data.text = `${ templateText } Open this link to connect.`;

if (path.startsWith('/channel')) {
data.title = `Join #${ roomName } on ${ siteName }`;
data.text = `You are invited to channel #${ roomName } on ${ siteName }. ${ data.text }`;
} else if (path.startsWith('/group')) {
data.title = `Join #${ roomName } on ${ siteName }`;
data.text = `You are invited to private group 🔒${ roomName } on ${ siteName }. ${ data.text }`;
} else if (path.startsWith('/direct')) {
data.title = `Chat with @${ roomName } on ${ siteName }`;
} else {
const user = Meteor.user();

data.title = `${ siteName }`;
data.text = `${ templateText } Open this link and connect with me.`;
data.url = new URL(document.location.href).origin;

if (data.url && user) {
data.url = `${ data.url }/direct/${ user.username }`;
}
}

return data;
};

export const share = () => {
const data = getShareData();

if (navigator.share) {
navigator.share(data)
.then(() => console.log('Successfully shared'))
.catch((error) => console.log('Error while sharing', error));
} else {
console.log('Share feature not available');
}
};
1 change: 1 addition & 0 deletions client/importPackages.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ import '../app/ui-login';
import '../app/ui-master/client';
import '../app/ui-message';
import '../app/ui-sidenav';
import '../app/ui-share';
import '../app/ui-vrecord/client';
import '../app/videobridge/client';
import '../app/webdav/client';
Expand Down

0 comments on commit 39efc0e

Please sign in to comment.