From 074051297aece72b773f6945f45dafb62997b430 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 12 Jun 2018 11:11:43 +0100 Subject: [PATCH] add a ShareDialog for sharing users,groups and rooms Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- package.json | 1 + res/img/icons-share.svg | 6 + res/img/matrix-m.svg | 15 ++ res/img/social/email-1.png | Bin 0 -> 2510 bytes res/img/social/facebook.png | Bin 0 -> 1201 bytes res/img/social/linkedin.png | Bin 0 -> 1366 bytes res/img/social/reddit.png | Bin 0 -> 2279 bytes res/img/social/twitter-2.png | Bin 0 -> 1519 bytes src/components/views/dialogs/ShareDialog.js | 211 ++++++++++++++++++++ 9 files changed, 233 insertions(+) create mode 100644 res/img/icons-share.svg create mode 100644 res/img/matrix-m.svg create mode 100644 res/img/social/email-1.png create mode 100644 res/img/social/facebook.png create mode 100644 res/img/social/linkedin.png create mode 100644 res/img/social/reddit.png create mode 100644 res/img/social/twitter-2.png create mode 100644 src/components/views/dialogs/ShareDialog.js diff --git a/package.json b/package.json index 96c37a61c8..15080456fe 100644 --- a/package.json +++ b/package.json @@ -80,6 +80,7 @@ "optimist": "^0.6.1", "pako": "^1.0.5", "prop-types": "^15.5.8", + "qrcode-react": "^0.1.16", "querystring": "^0.2.0", "react": "^15.6.0", "react-addons-css-transition-group": "15.3.2", diff --git a/res/img/icons-share.svg b/res/img/icons-share.svg new file mode 100644 index 0000000000..b27616d5d5 --- /dev/null +++ b/res/img/icons-share.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/res/img/matrix-m.svg b/res/img/matrix-m.svg new file mode 100644 index 0000000000..ccb1df0fc5 --- /dev/null +++ b/res/img/matrix-m.svg @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/res/img/social/email-1.png b/res/img/social/email-1.png new file mode 100644 index 0000000000000000000000000000000000000000..193cb659da5d4adff51376f3fc75cc8609c803fd GIT binary patch literal 2510 zcmV;<2{HDGP)HtMRhk?0buDKu#&buo5IY}eF4AYO)9Jd1n2=li0!+-J|d^Tv3N zbTszZ@4j=+J733CzuoBXMFZC_b?x4zEDZw zLKRx~X6DZ_-)m8LI*N#E$nr@RgZ!HLXUr%47PQ7k4~R2wXWq)Zrb348X6|G@#GLeF z!GI5I)HCm5?q}XxLFGxTy;t08m$>&8HNb<+z0BWYZlKwt264|`A;YX2U^(-v%tu6$ zyHeCBWO!91*jX_ElG~fi8))tjWO-f4R#5{W{(dSF-dv-&knNdD7yxDJN6b&s+^3yF z)`(v?Ajtf4QPZo19uO5`6LXDKx%wM2u)&yA4)EecQV!F#z$IyX_ET#>PFGEaXW&C%=Qc}f)~%f0PE(O3LM1qxrw ze8P_!-!d;q8yjosp2o=g%9ct+*8Oj6h{Ho^O0Y4?AT(6BFb|Y!fIkZl(53~U8hWHT zMw=JcQlO@M@A=1Ao(>G8=wC@~L%;*>D8&GXnZvqw3A3`FYl_mgW%DQ=lxu!ATcq<7 zMLLtVC+OwuEzQw@r>DRpzQ;y5`oD~>c-urXf2eT)@;dUf20b0?j?T%bQ* znxI#h`_qLPbHxT;F|Hkbck8Q3tG&1f>q+}I?5y2J<}GqDW7GH zJ5DF*$WZypn_jf#tua>uM4q{6K}g37w#$IfRvqEKu`+J#kX89d|2?kc@}&^)z>_`W zbP+(oLLJNNbgIl&XAZboXOe>wcl%ZLgtx2ra!EBCLSG*b8JR!KzpUWgG0fFrgcTgj z6zT1B-T+5d!teXuNztBFaU0IKYf*%L|E`k3*9e_Yng+OE$Mqk(HfH%3~eRk0cQd(f$lOx07+q; z%9Riv@YYJt4`n=YJ9ZoRAQn^)Rw#TXWycNhvfN~y0lG~35PQ~eR>=#Xa|6tFr>amJ zIrgo}Twql9;yF1wLwxRIe4wK|Xee870iLn^B;y2oo>>>yI^wt!SG6kp&LaD;<(KEP zQdG8%cjfC`CBilG(sqQsrfVc;gwI0$r+uySX{|$%Gajh%G<${hf31~Bfm)RffLL=1 z`HH0ELFsRLD31q&34Yl=J}o>7u;7n<%=HvIeaQsg^&)nzJF#e?8g+dSSAXh1m!;@% z8E1N#4*eOq0YWuC^w`|O1W56C$%)5hF1ntxzO0M;2{$)Zx3{h95yM_Nz*$B|@)_<9E8XGZu|m+Cuq6`VSYq%hWQ70kF1LX?IY0e!kzyLieS2+7|DCVT$Y(d&R-g9-W%awny z#v3MwC8cg>OUzbbfI!hLYEmDHdbjFy#@dRuNs<>5k_?*e{$QOk@I-Tia(W*(R3?H$ zE^&qvTIXL~$i6>6c)Vq5%f4(a@<3C@`jSPGoLyG)X{lTM}b*jCaa_L(COxMDixI~iz3xQxz%^0&Zfjh71~>~e zDs*)j0KU6l2}W@&fBCfglomMQ==Jpm(9wN10Qp5@)Ljbgw>E&j9FGH}VE!kY%OQCk zJC`xQ(M*X9Lynskgz0w16&So?cIb0XaUGA#9*}s1G@cE@ZauXs?i!dnOBveYAvT0{ zGK5(mps^F|AiO?#V#JSN)1A_~=!sL~^w*J`A4`?| zhzyBxc!D$^iA4hZG~;;Sew{eRh67FmM0NS2JmTmUS>H3=3llgneWBbtqbvM)L)eJz zMeHJVY#irtIzSZQHBN=Q8EPZ;lZ8n?W51pG$Fe`n^v1{m<}Xoo)AyNoOg9spjvi+| zTE)sA6*`cv0RZ(LV*XtfD*v*Oz3hjj(WGzkilI45ko7(xJC$ny(+KS%o~j|{+e=Yi z#Q-Ml5R1>nmMx6#zIx0kM<;+KRBw+WeO zwhUnHtI=HSA;l9WA6nWy;@+L*EEMo*7k1OshIA)A^ zhi@ZkJcA@r`X!ordHOZK1+AHd*XNr=XNkwsRtkee$o*(uLX@r^5zh(H!3|eZxc>_< Y02w!UWX_nGYybcN07*qoM6N<$f{u#A1poj5 literal 0 HcmV?d00001 diff --git a/res/img/social/facebook.png b/res/img/social/facebook.png new file mode 100644 index 0000000000000000000000000000000000000000..6a29e3820aa997e5bc06d42995891ce570defd25 GIT binary patch literal 1201 zcmV;i1Wx;jP){WFb!?3z7NA68<|~E&O{8>Ez#ZokqHl4&r9Wg z0N0RH$a_dDXa_6TImI?;F2Et=81fkhxp*OqZ5ZPKtBC*<+&&^tfPO%>d|=yz3PAmD zkOQ9HkjA!kiV%Q?sXk;g=pT)2t3|D0(1d)!V|t>XhDV5MSgM)o15E>MB&5ic5OeG{5w+(Z%-Cd{(H5AqNFk!8kff%pI7bhof;DhdlLDra^`dG%oNEQ0 zpk6+emkUrQGNsMjo2nN9tn6#hFlZN5qm+~c$!1g7d;Y9%z~EaKIH$jXd-=C$5y;mL zc?+M=ZYvcl)iMIf&YwKE9dD<@k z1%(nY9>`}a2~Y{fMJ0^_g(6DsY(534Ddwo|55&sqIy7~>5h*~SBuW4^@a3yV_-G)3 z*o_QDn3?|}x{A#fkS(I*WV7;3r@4h?;b}5inJ%JaTJ=$i&+|*71xS-XpKJW^eQ5=L z{#p|*fT->9ptZawE#c={6zwVMYYl1vUNA1aB!I{00xTFviI1Ru?F^3dht{_NxoPUzm{UjYUHqC(z?^D_)0 P00000NkvXXu0mjf5Z)l0 literal 0 HcmV?d00001 diff --git a/res/img/social/linkedin.png b/res/img/social/linkedin.png new file mode 100644 index 0000000000000000000000000000000000000000..2b868a585ba59ca2f716f0a21254ccbdb3c95438 GIT binary patch literal 1366 zcmV-c1*!UpP)b&2Be0RqO@45R0W~Mz9=g~i=y;FTI@p~6pB_* z2nv=^U$UiG`cT>;6hc$dSOQVWmXsx_t+iFtXzH3pV-nMzGdUyU?##OLx4EZ` za+Aj4e2}>eXnsK>$hXKZk$oZy5JK)j#*vK<)*EBKj~qa@BhMf+PE;;AP)8Vf2zeEG z++pXl(a86>%J&S$6kUhxHxRaYLMA?QO?qG`|0CjHt z$aNqN$d*fNo2vp)`#Z-So@fZMZ719ifQG3KuFby?6y~-+v&Q2vPRwr9vVgo-brnEUqkv6R$TzYfV%Uf=I`7 zZb`U8#7Jn>>klNI9Q$ZN3u*b}lwtx7J;kC;*{}ow)2>Y5NK-^3%iT*zzGclEOp3c!V z!4c0EpczcA{YaA$l%Asy2>x+XXp+2==jz?)WTq4EA$_kdUX0-7-O zsS)rR_z$nDO@KOum=6UYpCcr|2JkO7P#@4>rDVtU7O0qOyq>b{^B+zBzZ3{4>2z#i z71YfSK~M@nZPh$wWEswkWY*VP!q_A zAixj54_mrMpy5@XW9c<#hDxPH5McU0<7;;xOg^!EP_iz-O)qqI_a>*@sCI+|NclJw z9wGq-d@MlH?-7t90lIuFKo`|y%}41cu~By{>vfKD|LA|!k$Ktd}(ug^Ne6#M+x zdx3Tz3DB;c3#d3PN?PnP((G%F05mB&=>q{yYA1k_&c)FZc78PbAqRB67kCFsV{eci z-qnV`UIeIpL3ar{-<|EekpP6vDWG(UoaCc=X#rLS?d)kh^pu!` Y0BLR|kwK3)O8@`>07*qoM6N<$f)AK>P5=M^ literal 0 HcmV?d00001 diff --git a/res/img/social/reddit.png b/res/img/social/reddit.png new file mode 100644 index 0000000000000000000000000000000000000000..bd6131186f990ad2902c6d76165f5bf7e6457244 GIT binary patch literal 2279 zcmVAGR zp+O)Z${7Muj+U!jg-U75B}dC?p+c=td_Ued?6jTT&au1Q?Mq%}I-U8x_uluu-#cbD z>~7ktpBX+>N=9x{hOnI2E+gWx5Las zDR>C798j|P)d1Lk%N5`S8#Pg~edP}WAWSV`evg8mW++)Be3b`;Gp|%JJyhrw6(J@u z-*M^z^FvH|jm9h49c_UmD>>#ju6{bZFvIlsG=2kluU+oCO(0ByR6rot(2Z-WPqeP0Y1>FgP!jx+)GqmCfi}cy8?ba7|at> zdF46VEh!?p@|V?_ld5CDKtFeKJk)Q>;Vyeo0LpLpmgt!jqAml3HM({|wvN5d5_Hbd z4DeFm)04&$^6n}5kN0~4ev3aM>Nl3CRcE4#a-w2|6Spgz6ihi<7(|1kk6#oGa|v1l zsUiHsop|M2)VvSzy|hGD_2Nl6o;&8xB|x{iFAM-bykZN%u^-#T$=}Gx^0rBq25Q-X zhv)DXGgtttI^q8EGWS@K?F>+!#X7W!=uaN^)(yD^uj$-R#s{6}WT_~J=)ZD1Mra8G zB&tq|c|z=cl7X~E+p5>$j{DYd;@MG*qtT_)L?`$2%AR7^Epi*lXj`<37Eg)pD^UW3 z9HC%08|@-d{{*538diM{A(<1sJ70BA4IF&{*DrKWx+s|NJVSu58&^b&N|2twy> zCOVpF2c;EA@>c0Fl9e7;)r&AD3<_`PJz8X{xJi_eYPL4eC>0yX(<}G zEQdb;8ffP-xAKV32v7KX^Fj$*PL*u%Cgz$jo4n0jgcN zlA(_Oifx27m_?J3?kxc-=Kh!ySL%atQ{=xAkag ziMug@o?Ts#Ru7cg{*0&)2FSB#yEBrYfRL^Rnve$|?qmBE7up>q*S-f};{0qmfAlFS zWQ+)18>G+LYMCJ*`>-kA6Pw2-s;HFhq$iLM1K3a9kf*~7An4O?N@%Q6ImSo}8wC`U zY8K_)rE$;8T$>Gg)^lnLgCb7=_(2Byl%OrS`}GYGO`ZksqF-Rt06`ZB`F`GZX?9jed{led3lxlLUwKXE`)`I&%kFjrO6Ub( zWgsY&&tAcbWJ-nTsrdn8X}tq)Jp*_d>H`=J28EZw+nmv0q;&dMW5+D_2C5U<+%ST+ zx=2*e&O+X9t#>cD0*{FsE*&Cm+hALq&2y?efIm*}0iX|rU5MJms8x=38_DHzD~IF?KnMUV zIpHL}d!sac0T>*w#{)+-UXQyBZb+s2OR0M0jSK+7%eEc$Q28B7H>%A5pk(sV_xM3V zWlAS9Yk+)D4}>Tsdn)?8#in1F)9Zoq=}H%}Y5>qX%o!o9e1_72>>2<4yqQduVTY;sdbN&o`(!1Ht=6#9-wiHO#l`2U%nTHjsySn*+Q-j< zHh{i>>cl*Y?6%p>cXDQ_xl(=MePMq3^*DNr`1lIV`&b_+{Ts=Tr}y|;(69jfd>&t* z;9Grkox3T6L{QBxbgl|r`D#DsstT^ypThkwzyNr(v=B#;25kTU002ovPDHLkV1ko1 BJN^Iw literal 0 HcmV?d00001 diff --git a/res/img/social/twitter-2.png b/res/img/social/twitter-2.png new file mode 100644 index 0000000000000000000000000000000000000000..84f8033a30c5cef33bb14ee59b5b8d5398b9162f GIT binary patch literal 1519 zcmVeqY zO9dhH4@opc3o1&nPzZ!p18Iw=v9U2GwXM;_%UyaVX?jU~@A5XDm+fVDXLfJbe(-U} z-QMhb-@ci7Z)VQ7qiYasMk(?!WDT+!Sz*lx+cCL|#C?g$#mo2=YBIunmq2P>DQ+Jj#PywouA8oZnq0jU3V@_^?y1lYFs>=1yasW#-R;C?i*t*WePFb8>z=X9^&Ii4Z5 zA!kJ+;GoBx*RYvw7wQ5b4k@pqiG8rt1sae?jNYkwWiC8hQJj1w3|zei9}kVgP<$ra zA{^nmqT7rB<=pQL4J1$BQ3x+om4M>=_p|lE0=RcoJ{;tlY-$ID!iHZ*Em>2HQh)6iqk#t|Hq!xR6bRJMu$t< zY(_z&o&X`Zc@Rn$U<25@lH)eivd@c&&`vw=c5AL5Iv=eRZf7zv2j?fIp>sHz%rqqw zOubqJJmrPQMzaZJnEUTv16%GCUJiUh>jE?=)O#s@DY<&SG6;7U3T2q&bC3ksJE&OOO87aR-l~KLPMi&V{=kUT-TR1m91qQ~! zB(|3q!|t^uZi$4jHV6_v^x>u$3&<^DV|4WD0%!MTWV9nh|2f`lHC!LTnjEu%157Al5JU2#6_t1C-(C6U38 zeg4nBK&wcLZNH8~Vt(GS_@%DYu-bAR*P2=jX!t-REv9Aaj|L--cH$>*UuorMG4^$d z08|tm5;5rO%M-H7R70q;wkCKewE$Ffz7%?l@1GxaOoYUo=`I&Zf5?i?1ude*(YrtW z3CA5c7Bd((y(ZX_{($w$H0mGSB8Jg}X&v|r-s$@TYlZ8!3Gn45QzCb#_Weu(5MGk8 zP|`Ct39t2DP7aQ=DkKXeFwHt=B9n&ee)eezd>Q^SLmQ@_$b4e7k?~MT0o)Z(p;*m< z)p;u*VB+)$tqD>h)G-t_8~(eH9eQ76S`(xn(7_^Ur$%V1l(4I77Kd--e5Nj-;T0`q z^eEcd2e2vt9W>sJJnli~Pq6L6ho$MP>$Xf`L^EUlUaQDN!Pyf9B){oJ3!T)~al*_ZwiU;t$x VVe!_=*FFFM002ovPDHLkV1goAzuW)- literal 0 HcmV?d00001 diff --git a/src/components/views/dialogs/ShareDialog.js b/src/components/views/dialogs/ShareDialog.js new file mode 100644 index 0000000000..8bfa0ad931 --- /dev/null +++ b/src/components/views/dialogs/ShareDialog.js @@ -0,0 +1,211 @@ +/* +Copyright 2018 Vector Creations Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import React from 'react'; +import PropTypes from 'prop-types'; +import {Room, User, Group, RoomMember} from 'matrix-js-sdk'; +import sdk from '../../../index'; +import { _t } from '../../../languageHandler'; +import QRCode from 'qrcode-react'; +import {makeEventPermalink, makeGroupPermalink, makeRoomPermalink, makeUserPermalink} from "../../../matrix-to"; +import * as ContextualMenu from "../../structures/ContextualMenu"; + +const socials = [ + { + name: 'Facebook', + img: 'img/social/facebook.png', + url: (url) => `https://www.facebook.com/sharer/sharer.php?u=${url}`, + }, { + name: 'Twitter', + img: 'img/social/twitter-2.png', + url: (url) => `https://twitter.com/home?status=${url}`, + }, /* // icon missing + name: 'Google Plus', + img: 'img/social/', + url: (url) => `https://plus.google.com/share?url=${url}`, + },*/ { + name: 'Linked In', + img: 'img/social/linkedin.png', + url: (url) => `https://www.linkedin.com/shareArticle?mini=true&url=${url}`, + }, { + name: 'Reddit', + img: 'img/social/reddit.png', + url: (url) => `http://www.reddit.com/submit?url=${url}`, + }, { + name: 'email', + img: 'img/social/email-1.png', + url: (url) => `mailto:?body=${url}`, + }, +]; + +export default class ShareDialog extends React.Component { + static propTypes = { + onFinished: PropTypes.func.isRequired, + target: PropTypes.oneOfType([ + PropTypes.instanceOf(Room), + PropTypes.instanceOf(User), + PropTypes.instanceOf(Group), + PropTypes.instanceOf(RoomMember), + // PropTypes.instanceOf(MatrixEvent), + ]).isRequired, + }; + + constructor(props) { + super(props); + + this.onCopyClick = this.onCopyClick.bind(this); + this.onCheckboxClick = this.onCheckboxClick.bind(this); + + this.state = { + ticked: false, + }; + } + + static _selectText(target) { + const range = document.createRange(); + range.selectNodeContents(target); + + const selection = window.getSelection(); + selection.removeAllRanges(); + selection.addRange(range); + } + + static onLinkClick(e) { + e.preventDefault(); + const {target} = e; + ShareDialog._selectText(target); + } + + onCopyClick(e) { + e.preventDefault(); + + ShareDialog._selectText(this.refs.link); + + let successful; + try { + successful = document.execCommand('copy'); + } catch (err) { + console.error('Failed to copy: ', err); + } + + const GenericTextContextMenu = sdk.getComponent('context_menus.GenericTextContextMenu'); + const buttonRect = e.target.getBoundingClientRect(); + + // The window X and Y offsets are to adjust position when zoomed in to page + const x = buttonRect.right + window.pageXOffset; + const y = (buttonRect.top + (buttonRect.height / 2) + window.pageYOffset) - 19; + const {close} = ContextualMenu.createMenu(GenericTextContextMenu, { + chevronOffset: 10, + left: x, + top: y, + message: successful ? _t('Copied!') : _t('Failed to copy'), + }, false); + e.target.onmouseleave = close; + } + + onCheckboxClick() { + this.setState({ + ticked: !this.state.ticked, + }); + } + + render() { + let title; + let matrixToUrl; + + let checkbox; + + if (this.props.target instanceof Room) { + title = _t('Share Room'); + + const events = this.props.target.getLiveTimeline().getEvents(); + if (events.length > 0) { + checkbox =
+ + +
; + } + + if (this.state.ticked) { + matrixToUrl = makeEventPermalink(this.props.target.roomId, events[events.length - 1].getId()); + } else { + matrixToUrl = makeRoomPermalink(this.props.target.roomId); + } + } else if (this.props.target instanceof User || this.props.target instanceof RoomMember) { + title = _t('Share User'); + matrixToUrl = makeUserPermalink(this.props.target.userId); + } else if (this.props.target instanceof Group) { + title = _t('Share Community'); + matrixToUrl = makeGroupPermalink(this.props.target.groupId); + } + + const encodedUrl = encodeURIComponent(matrixToUrl); + + const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); + return +
+ + { checkbox } +
+ +
+
+

QR Code

+
+ +
+
+
+

Social

+
+ { + socials.map((social) => + + ) + } +
+
+
+
+
; + } +}