From d7e5171bfabf48e69112190b7096268222979c1c Mon Sep 17 00:00:00 2001 From: Konstantinos Sideris Date: Fri, 20 Jul 2018 12:02:35 +0300 Subject: [PATCH] Create user profile modal --- CMakeLists.txt | 2 + resources/icons/ui/black-bubble-speech.png | Bin 0 -> 511 bytes resources/icons/ui/black-bubble-speech@2x.png | Bin 0 -> 627 bytes resources/icons/ui/cursor.png | Bin 811 -> 499 bytes resources/icons/ui/cursor@2x.png | Bin 1148 -> 640 bytes .../icons/ui/do-not-disturb-rounded-sign.png | Bin 0 -> 746 bytes .../ui/do-not-disturb-rounded-sign@2x.png | Bin 0 -> 1217 bytes resources/icons/ui/paper-clip-outline.png | Bin 1121 -> 596 bytes resources/icons/ui/paper-clip-outline@2x.png | Bin 1852 -> 872 bytes resources/icons/ui/round-remove-button.png | Bin 0 -> 659 bytes resources/icons/ui/round-remove-button@2x.png | Bin 0 -> 1039 bytes resources/icons/ui/smile.png | Bin 1317 -> 775 bytes resources/icons/ui/smile@2x.png | Bin 2536 -> 1320 bytes resources/icons/ui/volume-off-indicator.png | Bin 0 -> 827 bytes .../icons/ui/volume-off-indicator@2x.png | Bin 0 -> 1254 bytes resources/res.qrc | 9 ++ resources/styles/nheko-dark.qss | 1 + resources/styles/nheko.qss | 3 +- src/AvatarProvider.cpp | 2 + src/MainWindow.cpp | 13 ++ src/MainWindow.h | 5 + src/dialogs/UserProfile.cpp | 153 ++++++++++++++++++ src/dialogs/UserProfile.h | 53 ++++++ src/timeline/TimelineItem.cpp | 17 +- src/timeline/TimelineItem.h | 5 +- src/ui/OverlayModal.cpp | 10 +- src/ui/OverlayModal.h | 5 + 27 files changed, 265 insertions(+), 13 deletions(-) create mode 100644 resources/icons/ui/black-bubble-speech.png create mode 100644 resources/icons/ui/black-bubble-speech@2x.png create mode 100644 resources/icons/ui/do-not-disturb-rounded-sign.png create mode 100644 resources/icons/ui/do-not-disturb-rounded-sign@2x.png create mode 100644 resources/icons/ui/round-remove-button.png create mode 100644 resources/icons/ui/round-remove-button@2x.png create mode 100644 resources/icons/ui/volume-off-indicator.png create mode 100644 resources/icons/ui/volume-off-indicator@2x.png create mode 100644 src/dialogs/UserProfile.cpp create mode 100644 src/dialogs/UserProfile.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e3203cc7..1a83f002 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,6 +152,7 @@ set(SRC_FILES src/dialogs/MemberList.cpp src/dialogs/LeaveRoom.cpp src/dialogs/Logout.cpp + src/dialogs/UserProfile.cpp src/dialogs/ReadReceipts.cpp src/dialogs/ReCaptcha.cpp src/dialogs/RoomSettings.cpp @@ -265,6 +266,7 @@ qt5_wrap_cpp(MOC_HEADERS src/dialogs/MemberList.h src/dialogs/LeaveRoom.h src/dialogs/Logout.h + src/dialogs/UserProfile.h src/dialogs/ReadReceipts.h src/dialogs/ReCaptcha.h src/dialogs/RoomSettings.h diff --git a/resources/icons/ui/black-bubble-speech.png b/resources/icons/ui/black-bubble-speech.png new file mode 100644 index 0000000000000000000000000000000000000000..350189b12d9f58bedfb54ab359f995efb63be8fe GIT binary patch literal 511 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5m^kh={g8AI%&+V01C2~c>21sKVlbQ;8lKmiuoK+=&YxUV~EG`qf>PGm<$D4_v_th zQ1F^k2Vr5?p%PcPW>4hp=S7gd&8_6#e%A6GYEZav` z#)8u%x~#Tg+H8gmUEOCCtGpW1B*mWzwAXv2Im~iA9lKzr!Fy(&!j`7xq6J&4G%6$h zrLv#-pi}T@TCiEz_22uOCvp`W+gPVx+Q6}pRYlJy@`Y?o%pQg%E$cP>%H5=Z9#buG zjVMV;EJ?LWE=mPb3`Pcq7Pe1_oA!##Y9r+6G2e1_q4w&-_s|>Y&8K^-LWJ7R%T1k0gQ7S`udAVL@UUqSEVnM22eo^}DcQznrFnGH9xvXNS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VW5SkPk z%q>ycPMJjbQ^VxRS0pC>z;8z0+>JA4 zJ}Zj;bN|e{Kh>5il#&n5Y6?>1zNT}+!lixA+^!Pa@+T!)4KcAb^DD2`{C(9Qdm`xB zokY>b2?l19*(KPyqS_d4J7nHs6pF57|H01ii6y6^e}(Z9ZCy{jtzA(sye=8uXJRj4 z_^B5l<-ETqMg7kc#YN|)G;Vp~_k!V=qQ7H*pv&BOTOPQj@I7#Q!oa6s{jlM9ht;F& z4b}^pEgTNDn;uwgdSJ7z!ztY=UpNDe+5+Udob&p{7au1 zuf(tS%-q9j_0j3Uzb{*#t()(9!L}@2V9WWxoK628{B<&z@kgzR)q(jS+k&@Zu5k*68eoAIqC2kEG^DBS}fk6^vLvVgtNqJ&XDnogBxn5>oc5!lI ZL8@MUQTpt6Hc~)E44$rjF6*2UngE{s>6icj literal 0 HcmV?d00001 diff --git a/resources/icons/ui/cursor.png b/resources/icons/ui/cursor.png index cc7a247767d09eb60debecb6e99ac4edb8c97eab..9b3addee96a2445783e1c69b9fddf898753b96cc 100644 GIT binary patch literal 499 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5m^kh={g8AI%&+V01C2~c>21sKVlaa*O0o`bS)PsbkNhqF~sBe(W$;%hYUno?7K@; z^X_PHc-geHUp)Lmbl0W5>#8PwQ~JiU@I%as0Pj@?SC+7C;;b<^`MdF9Y05%Ip7T@J zGF9wI@n6Njv-r`07{(j=jXE!s>?V|28BM4yaZ%_lIJnL_faicgUTov5jFyKxw=nlg zY(BK{pzZmW*Tc0>p7^Nm5WSi0%tjSXC#`dHRyZ}3FI^*TaePVP^OGlqT)ql8*0}tX zuGUy$KYh~`pCD^)W>=}qO97(CcI}9Ga@B0hyRLn5wjV!)0R6(CTH+c}l9E`GYL#4+ z3Zxi}3=A!F4a{{7EklfqtxOE8jLftRjI0a{wnT`TplHa=PsvQH#I4~d>$(o021$?& s!TD(=<%vb94CUqJdYO6I#mR{Use1WE>9gP2NP*np>FVdQ&MBb@0HBDf^Z)<= literal 811 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}oCO|{#S9FB z8$g)xg!DSry^7odplSvNn+hu+GdHy)QK2F?C$HG5 z!d3~a!V1U+3F|8Y3;nDA{o-C@9zzrKDK}xwt{K19`Se z86_nJR{Hwo<>h+i#(Mch>H3D2mX`VkM*2oZx=P7{9O-#x!EwNQn0$BtHPq<;xTayvjlq+`>nL4|)3k3ZR_`A+k zUgGm<-WK7=)mx9(H!oG!e|_+NHFJgQ`ttuDxt>Vfaz1=e_9x5vg`y^TJNnP&SPAZF zId>u7`%TMDj>gO#!_>rjp@QOt(UAalW&-Y z%&`;KQQLHx+hXZerm2?NwY(c7JiOwCeV8x4%x+$MIlA%cm)b4QnYDfvd3xQK`SZqJ zm`^}np=5sgzVBC(f61RH%GvO9JO76U)>$*0l;Z=B*Q(8P*xYCOUF`CH$2jJ^!dIsA zKQ6phto!4p@QE)wAA43RUzVRTONsf`y=ajYYxQ3`oNx%K%1cO9(Aqn-@x_-gwndkt zfiB2TRM4!=Wj^^bTiU}fKI_0=&iIWpt6mA-kb9^0*7WVy>A?rwcU8Tz{Q7^o>VLod j8?B6e7x+$9t@+RRul(=f_MKWHpcL%s>gTe~DWM4fg;g?E diff --git a/resources/icons/ui/cursor@2x.png b/resources/icons/ui/cursor@2x.png index d02d29fbccc75914b31a6fa87f67256ed27831fa..89a26cad6ba85fbd61ef5cbf9b52236df8783551 100644 GIT binary patch literal 640 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I0wfs{c7_5;mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VW5SkVhdQzWExo254t{LS(S8AOmjWQOwX!k-#xw?&0ha&_L(nV7+ggzrZaPV zlUQ_!MSz2E#)5-D%4yAoWG0uFu^lQY4IAwhKPm0yoVa~wvA#>t<&6_c7>+xgVbF78 z`{k6wFo$C!Ye$RD*OnB<0MSXZ4xS!%4c!y;gcX(x=r(wq;3!pdP*c3c5SVwibqC`H zfufR*1cfCnLbEdNFa4@y)FHd}2bl>!K@gXVWoLq)^ zuP-~Pr`O80++aHL`m)1sz7u=w!WDlqOnOz!?6umzgLheKXamp3Qm#GvPKWYe)G90G zAN_Lp1#{oy`Pm*TbS1ZHs&0FFrJM6>mfM~=LF=DiVPq|Iah44VJYI6dQMEM0TQ*Gi z_}44!+^;6{{=C@rFDLxS{^OE5BH=c7j)t5A2DWO6YeY#(Vo9o1a#1RfVlXl=w9qv$ z*EO^ZF*3F?F|aZ=&^9o#GBA)bP0l+XkKUVq(z literal 1148 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|I14-?iy0UM zH-IqX3H7fbKm{q8ArU1JzCKpT`MG+DDfvmMdKI|^K-CNkHWgMtW^QUpqC!P(PF}H9 zg{=};g%ywu64qBz04piUwpEJo4N!2-FG^J~)icpEP_pAvP*AWbN=dT{a&d!d2l8x{ zGD=Dctn~HE%ggo3jrH=2()A53EiLs8jP#9+bb%^#i!1X=5-W7`ij^UTz|3(;Elw`V zEGWs$&r<-Io0ybeT4JlD1hNPYpzh2qfLoMT4D}VzfBF@P1^R}12KsQ5ff{XqezbBf zN=+=uFAB-e&#?nJEi*5>I61K(734r0eRLI2D{b^a?m%)E#M59=ps($?fI49zXvcNu z__ACE2BwXkE{-7;j8CJi{bU?Pw)E;c`8hmlVK^DnaO8+X!u(d}gmpKooQ zAF*c+KTzDj+GpO7=X}J|L`6<+{+APVT!o?!-Thf-IL~3NVB)LNI1uwF=)d)e^_6-J z9sJ_vf->3P_fGOxJ$ERe_S<7Emzu^k$FIbe&MUq@_1Dgh)f#zM&il?`Em&B`3DhR! zn($w3u}b0PSJTz>zMg&iduzw+;QeYJ18Vzjn?wniFRaskboOe#@1B{zRQ_>BFa#|O zjsCjsywJy0ucDRpwu^?(Kk_qqG3)B?Ew>hZ|1+&~HG}KBUp4~ajGOB2s~2jo-o>#l zYxCLK{3DT5bc*jQ7g{QL)}B8y`Rf0S66?vEf^WTuuiobPPuw6?VD)^@S--{4oeZAx zqV_+pULAuCJNF0HiXPR2njfS$WWC?GXHwX|>!(*03feIJc+zq&dfusf7fRnZe&w;< zY*F*-vB|deiZ{zQ%AVcPcVvCzTFL8w-Y<^%sTsHB@6PY-h4T9}O3o|_-gzZK-m}== zwDHF4mkrSgIeGna{b&95n)mr)vPbQ7>j*yffWJEa6I+v5QS4e7Hqp zIk4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5m^kh={g8AI%&+V01C2~c>21sKVlaa7Za)Y|3I99fpLeYi(`n#@u^q$dq)R~9Qf#O zq@vfS#ONr)J@F4?lQY}Vm976QRsXwkG+j`vUU+wkgJWlRwBm(}3auBe>O^_0bAEUF zbavdM>gRg=?|#p_|9wuE&C2ZGFPhuf)YR&JKU^Npni7A0^MvAgU*F`nXIm}XSx~gh zDr>ceYVz;dlYiKjzdyFvzRbkbbnCPSd(Zz{7j6GdWbK*Kw`=dpznXp2exA&F_jwPJ z-}WkQ5Ty}X*JS)*_E+4a_`zd{yww@jUU+~l%W&-SyIk593C?&w%^-QxG0 z%Z))S&tLs-++=m>-u8J94!^1JZ-3>G?fvHQpM|GhMa+Mx-@PkpN1jh?+M4_*o&SG~ zjEp`#Ixw+VebvXj!%2}(7JbQzo<8aH)=8_E9I2{jPInL1Iqq=>6xXUHt`Q|Ei6yC4 z$wjF^iowXh&_dV1T-VSt#K_pn$jHjbK-<8`%D}+-gk=GWhTQy=%(P0}8oZ`9o&jo* v1lbUrpH@mmtT}V`<;yxP!WTttDnm{r-UW|QztN| literal 0 HcmV?d00001 diff --git a/resources/icons/ui/do-not-disturb-rounded-sign@2x.png b/resources/icons/ui/do-not-disturb-rounded-sign@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..24070444de511c49357788f36d66bca78975737b GIT binary patch literal 1217 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I0wfs{c7_5;mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VW5SkwZF8ZK*RpS zhP=JpeoDtOJx+yq1T?EEFLf}HX!c&PG2;h&$9zX`si+Muj6ph*7X=($-QOI0AhN83 z+r_abSmN>Qy?Z~~&b|4nto+;U=WpK3X^fw#a60|cd(K(!S03Y^SF`;^q>q{9!_76@su449(Qe9#uw_<oy}J+NTuw_4u5X8mEqt325qn|WV!MlOGK*~Im#c$w3IuRrch@_Q*7 zvRRmapZD}leu*c|eilC5T@o1}%5(HtxN_WY>s0HwmCskLSQ9iuI=21%gh0O3gR6|z z#q2nG;v>UtrR`~7#l5<&a@TcRKW02?HH|Gxe9?jV7r*wkR|b|{Ja5*zxl~G8PT+dT z^8J^$wFK$8**tOWT^pBnbJA75ia&cEDk}bIH9F9;;lKOFM~r+rTj$MeNL{!?&{*!8 z%h}W$qSyVk(rjkziF);}Z{ju)vmcM8;~#dP_<2<6yPlM8o^E{R&BnAh6%D(J+2!0C z+QUqY1w{D!14|Sv?wK)%z3gG&=X`y9hQwBLeFYgg%jcVzCo3P=U6$~Jr{%cvy;EN7 zX>JYfcfW-N|9NG_Ue~)WE@+QOaLi^ADV<|BRX>igpAPrk+c!6k`C^aU1CPCZOPw!G zSZ-2O6J+r`Uti_rq^HS8oc*3p@?8GK$jxTXt2seeb?5i<&cC|*>8ry}bkz17+i5i+#%4Bb+eT3^44u}kCQC({eA!V4H; zlny6;wDzh_tu;0E5S9Jsy5+gVl1r^G53S#8^;0j=>H@2lwxU&nR&;*G0-=(Hx4zAe z{h-d~>ieW7V}%$GpXu)hJ`yh;P6}NUr(ekx)_ibYg#+KZm3zKznl?#AechacPu~CR zv|amYiLD?nUqo@iouHh8C7lz#Z<}}cmi70{Y01amUVl2xN>?s(qJr2OC7#SE^=o*;o8d`=J8Cw|{Ss9sX z8yHy`7-W7BL)DO*pOTqYiCcrj+I87L8zezC1m~xflqVLYGL)B>>t*I;7bhncr0V4t VrO$q6BL!5%;OXk;vd$@?2>?_}6I1{I literal 0 HcmV?d00001 diff --git a/resources/icons/ui/paper-clip-outline.png b/resources/icons/ui/paper-clip-outline.png index a30fd07b9da6fc00409d19b8e5e390279184d658..579f564e7179408fbdccddeb60bfa2bc4e35a2bb 100644 GIT binary patch literal 596 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5m^kh={g8AI%&+V01C2~c>21sKVlaamlC+Fp3TI-z^LTu;uzv_{OuKg?Uq21;~)9e zR9!W>HS13uTXW?{@E*1>u}vE%n z+}{dXHwlZeR-WDX?f9l=u4lOC1+f*rS~?}}+N-PUR(B~?75e*a5b=J_GCQ>5!Xw8C zYyC4~uk2eKe6j4*&cc}yFHcO7JmulxIr~Cq=<$=jf4a)Gr9A6;9S?3@vvI}3ZLVE` zr?sYg{G0J?pMUuOIs4~6nEc9aO5?4)zn)+J#CVo(+m>0mS^B^LR4s9hC`m~yNwrEY zN(E93Mh1o!x(4RDhL#~l##TmVR)%KU21Zr}2KQ@LUq;c8o1c=IR*74~Iz{1ppaw~h u4Z-BuF?hQAxvXv0i>ry1t>MrKP@sk-m|UE>MMTab;dfVufyAu`tKo-FP)SbBnaEtPap}qq8Pro9uK;KZ$Kp$>0P@@gdk5)vUyR<0#BB|j0+tFmaFj= zO=~~V@r>2CsiVhW*M$|0qK+Xhi`5#NBsiuucj&1IeciLc{zt^yb2q1#);vtSyZ`ID zt=Dg*&%Y-6|GL_&wg)D68gwskac|)8y{x4)zg6YLrrFhAA!^!0*=eNjikgR&ZbEfHQrHkFH&c}KmqCeeM@DXB zMfj!I0Dr3q>lJ2kt_>5`exQ3oY32v(j}wX>9=~`#A=-EA!8fTR3;_0H;9ZU;T3S@Go*I0S& zjf<*NmkT(T>J}E}Tx-<>ywqOY`>HNhJ)Id|vp>*cj8lxWAD*Z^KN9vQn-cVm^^R zca|4FGcIg6ckhVmsnrivZ>)MZQ9sG)y4hqWVR4D8tnU}}bY?BPIoWSvr_@(hpAsWK z_Rp+2tudE8|MP5nCG~TU+Lr37nA`vlL!THOlg-j1hgW$9&F>k`hpj*c?>J3CM$e(#WV(g%wiQ>{*X3O?&S(tc z@_n((bW-h?SMF;sttg&WHuDEd)KrP)Dl5muUuD-^H}s#)R4M%R-5NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VW5Sk$~aeG|d z1bfL7?Pe2v4oS^Ze-!mxS3W}ReBLXSGliXIRvCil%@~VcO;K0UT>&n#0CZ9qs z&Im2Pepl${bdyN&{+B7-8b9FitB@0-gAqrj-By8CtqSO2y@%-#4LUBteH6Pr^%Y%cF)^! zZQWtsnZHgM?6eO(cyY5xZ{D>_n&$)`*T<`zk7`}HeA45RlC4~ig;v+S=Rf(wMqHuHM#15SCZ4V zpD~e7wCh@$5MiKp@z#k3hcDkW3ivj8ACh@%qnG*l7sILwv1`c-+QnzJuB}<-_fG3> z+i{D@AAAaQ*9fiSo_Oz`XteP4r9a}eFN9ag6#O>wx)m~`N-Hn^c;MOeiIQ?cFXZRt zIxkYZJ89JA#$z8(ClKI@)HwkErERK(!v>gTe~DWM4fJ*8q1 literal 1852 zcmZ8i2{fDO8crf;G7@6cogqe~sY6>yEK~IpV+j&lQDc-MDWS0?k|1=kr5&dBt&8eJ z7h`mysP>XFLKjOl4Q=V6t!1<*v0Y0Qb)(bix#xc8eA|1T_j#Y^J>NNBmY1gs0EO*!6B>(V`8Qf3~lg(qYVlmsi^rNhJ9tn%xF7#!5))~Y8 zQYe=D*_FZ{flp@>Oz}j*7iLAGjlv_~$YIcVERHXW6>YmMjTsxo4W+Xg+X8I}|Bv`w z(uT0D<9~GhZTeGG;o26i$o!{+w(yr7l`$ZYavYUx@5=|v%b1;hPFfwu%}oQNQM-nO zvL4Z~I!H$6ydw%Ha@M-mbnRPvUk%Cy4cv->+>K_x*WQ3pk&e;Ua?nB1D@!lv;u@I8 z{aRC+)z$vGkTmf z*nlB*tx74eN^>CPbr!Vs(2B7?$T_wD5rSL`zMqaP*|fX+fcDL?a&%sYo8$+K7R_%n zJlY*1DyZO#;b91(TT4itrO8f}57=C_ifF6G{XP>B-9Xo@ORj3Vd7D2Qzaz`}X$Fm1 z<#2Nu`<9_0zG7{39C}H0A1Y}eEz!R7p?&w;G#mp6K8;Q(uQ%uLPpZbRs?1~w*10bt zuT{^^-A!|nm`{d2H5?z|!;3*CWnBgHd`a(5z5jw;4&Qo2`FILkXgCT*Z*;SLfLEw) zS4+*erE+2Pde=9#HL~pbGvzDPqFNb-rY=5I4yr!jUJ4a0Y@+72H`a@m$M5B?OopD`I&2`ToRU+2bykWFXBgUX9?f%GSz)oZ8LufCU0QTYArBSQfno8_yk`M;j+ol&iz zIevKF(B;}bEr;g!mPk2l@gm7m?3b&tGy_uf9Q zrtG#c@Q8I~(50k;*SwO={bjPL*|A5aMvC?tqn9$KYHd66Dz{!@?ebdT{e^p|=b7Ki6l6ox?vxr!cLyQqjd`Wk9lj)sb*JA!>`XT*Y$@Q zD@U(kH4`9P-BU;IK8D-fXgQyKeLiYrNLIRby6(*H#SbW6Uel7Ck+6|&qGyAi{@}$x z&%Zq$Wg#{z4$n-TqKvPU}4H(}XIqC&U%1Zyu4LpWD93l;)VL6#sXsb)`@ZI?S#y?^P07K_cLXYb5tT4U3x`6n`NgT*`kh2MT~$k dEh|c9T`AFBw~_Ckk4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5m^kh={g8AI%&+V01C2~c>21sKVlaamljenvd(8^$Yb6Mhg^)&wtpZox5&Q`hqJnyiXkUTcusH{syCI!3LQ> z(GD~Irj@5npDC9r_2`k|;e(7qLP>T%p0G3ba#}9-IyQ4cp{dOQb=}s@6CWAxaIfOe z-oJUmcWuGwZ#9g<%hp6Bbm~5u`To(X;=WC%rZxl~v{QPZW!!hBdt&+z#_#6^V)=G< zx99NO=uB*movAvz_spHU&kvn16i(IqbNgHH%{{qK4oq{nq|*}+^jzwpmAKVh#RCEB zd=q+@S&Fu{ZE#z-V~R}7RJWJ_jca0Z41&wu`21WLD#VN#w)K9HHhle33xbHZlzGBwI%$5C@7A^gyV#7H3&*|BUD?3$+4Rnu0sQapj88WOsR(;*&&M&3X zf~nE}ePsWfTg&amuDZ4~u(f{rS3c?PbFPoCg@qh`c1yeT(t^GJnb>c#-3)rhbPgE) zswJ)wB`Jv|saDBFsX&Us$iUD-*T7uY&@#lx*viP<%FsgFz{twLAfa*h1{4js`6-!c zmAEws-eKkeYLEok5S*V@Ql40p%1~Zju9umYU7Va)kgAtols@~NjTBH3gQu&X%Q~lo FCIIs!@zekS literal 0 HcmV?d00001 diff --git a/resources/icons/ui/round-remove-button@2x.png b/resources/icons/ui/round-remove-button@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..6bc98e53dbf660d200e531d15b6308ab96019359 GIT binary patch literal 1039 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I0wfs{c7_5;mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VW5Sk?` z@{Wst?##KZv1QjD`kGpQzW051e%;>6#{%J86(I%pxqjp?J@4PPQP*vn(C;~)j@;LL z+8O*!b7tGQ%L|TYXl;pbE6JQ-&ipRmxtY=F%WwNB`u=^k;^w~-#i~WNTDgA9_$aZ- zD(m7w*}g4q=T=Oby>jm2Q!~TFUM_nE|%WnvADlv1@p#*Wd&1g_s=eP6M9nf^2eaq@Y2*NJ@a2onc})r z+w9p?=Iwbhc0VT98pdU4?2daB9HZU0$=dAR?5ZH=J-+6B6+(XbpLVLSMyIbl$b8Ar zbk>TPpn^gf>wmR_*-JM@o z&-{A&B~#4#wdxuNs=Cq`Cxu+QT#{fL$ayVz>w^NJfZrEVOf5_#v#(5E`ue!Z;~$0X z3y+=n!!LGt!$$t+Tij-!SIjM(pY!gimRZCnWN>UO_QmvAUQh^kM zk%6Iwu7SC(p=F4Xv6Ydzm64IQfsvJgfmhvQSriSq`6-!cmAExnD@QK`YLEok5S*V@ pQl40p%1~Zju9umYU7Va)kgAtols@~NjTBH3gQu&X%Q~loCIHFsukio? literal 0 HcmV?d00001 diff --git a/resources/icons/ui/smile.png b/resources/icons/ui/smile.png index 161d46d4c62f59951962924b22d15a9df25de7cf..17b3f10338e00ee3e8da8ed49e541a3d9aef3215 100644 GIT binary patch literal 775 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5m^kh={g8AI%&+V01C2~c>21sKVlaa7Z()lQ@zQ+z~>>uJU zB`s@E&|(xn&ZW1mskys@wVki2ua4)W%3n4`g}OGrR=rrRCPvvgGE91+nk^5~Vr0IQ zReay8R(XEL^>2Hg?k#`!|ITmw?{ogI)Yvr3ceh4IVxJzvdv0sQ=B?+@BWDX_xe`*e!mo-rgMAKI;mRO`CmToUcak*_nwTI=YKxm zy61>!dD!PO!9UiX4cE-ub=IjTCHYuo$(&XGXM*l###GwP=}u#tf9#ULS^MMiM-E?K z&K1z_!lv0<<`a9W_F7*QU)bhkv(v7V&Xqm#IJHc4?ru5OT5aVIqO}JX-~Dm7YiVe5 zw17>zc)6tHydD;d&U*dL-nC*Zx35ZUeq5*ZZ{^+BM?PB#v$)U9w&IfEY%8;K4MFMq+ ze5`Nhh)?OVy(?I7Jx=X_rK9GwEvrn~`(&**Ow;_NJ?Y!|MW^CV|EibK@znF`-?nF} z%(|(E6jYD>&R;w))|UO_QmvAUQh^kMk%6Iwu7SC(p=F4Xu@w** znrj;vSs572SISmK(U6;;l9^VCTf@8h%kzO6BtbR==ckpFCl;kLl$V$5W#(lUCnpx9 Y>g5-u&wghk1ysb~>FVdQ&MBb@0K8Z?g#Z8m literal 1317 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}oCO|{#S9Dr zY9P$myv;`xs30XXB%&n3*T*V3KUXg?B|j-uuOhbqsG5Pnrosxy%uOvxRH(?!$t$+1 zuvG%9umZ9{!um=IU?nBlwn`Dc0SeCfMX3s=dM0`XN_Jcd3JNwwDQQ+gE^bimK%T8q zMoCG5mA-y?dAVM>v0i>ry1t>MrKP@sk-m|UE>MMTab;dfVufyAu`tKo-FP)SbBnaEtPap}qq8Pro9uK;KZ$Kp$>0P@@gdk5y^xri8eqgDQcR2imX$^P%AyZfVt8R(B=MLHPX880*6^HfC4UuTRpLnli-52T0 z=N|t$yY*O?fx|TsA8vnx{d~U@<=^P7Tzh`TER*9>=?^v;^jPg(wfqcwqC0o!l@+Gy zVoAE$+gMsBS~S;kZo6cmpLdR9i`$j#T^#wzF+aoK1Q%@G(6%+EW$W9(PQ5*s0~W51 z>wY#xGhyuxVfhW^XLgJK-+R&|Z|Zj23w?!*_u9)JINsnm1~m8hod(mz`}T@0Y`@9B z;(_HI9%g5Wi7$Q#zH77mBI&)=x%0%V^QU&~eG_@ybd85i^!Ibp{gWdy^wOl3|5B1$ zyi@a!rQ4Z#xzY=6zxGr=u=Yz_qVAucTN19VJztuAaK)#mJME;ZIjV2%&b9A(d$m`k z{rp$ko~ieb-ka3zHGkuUnZaN8-Ei);eH)u2HL)bhowe+tHGl2w?$Gdz63O7j*XC&5 zQ2xcMwIjx=&QR{c#&a9m_r|pBy{&e-v)$c1CcotJfjGT{OVdBpA9%(ZbD$#g_a7^7 zYx!*tJ-)Zu%sYQ|RxoR|%i2Qm0PRp|$?sFjtYp$Y3E4G8Uv^-QKI@!uZX#E&?HkoB zy$8HsmI|1ie(1efR<2e3Q^L`hvxXUcJ1rNr16}r~0+AeCy_pS__oqY0fM4|YcHnF*lc`HLL z`Ys#)m;DnI6g_{VR>bL9*S<9$iJSW3xHY?|*>9E44xg4z4s92H$7GiOa`Kuh;_>SX zvtzezU#Hx3TH>r^W8u?lGI^%)iFY`K{~r1FB=trU*0V$_4ip+^3@kh4{5A9 w7%AcV>EaBjtmdKI;Vst0HC8c`Tzg` diff --git a/resources/icons/ui/smile@2x.png b/resources/icons/ui/smile@2x.png index acc439e9961b4f8cc76c2ff72c3bf6804d882163..b1bb50982cb486874945dcc40aac8c0ba5690e3e 100644 GIT binary patch delta 1312 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 diff --git a/resources/icons/ui/volume-off-indicator.png b/resources/icons/ui/volume-off-indicator.png new file mode 100644 index 0000000000000000000000000000000000000000..0ff3d30e92ad44cbe484045c2c37dd5270e1a30d GIT binary patch literal 827 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-GzZ+Rj;xUkjGiz z5m^kh={g8AI%&+V01C2~c>21sKVlaamsEGyKKC3@6Q`$(V~EG`saN*}27kEEZIP@3v}T$E3+#a_L3d1}KjKjZO*p5v8{lcHr90}g9FJz&2o;d0gCgWnGR@~>CkYw|Ze>hc6mfn{gH z>RJ?Jicjw0-T%lh&0$7}($}EhA{x&)9A9)YwRAEV=8Julc9iI6YdW%wQB9yF{w9Oj z$72k}9EZ-oX)p;)XozKbn4Dp6eaK!gN>Y(c=5>bdRfZfF=C_K6`m?KI`{S67d}&-N z&QxCdL@Q?b(JW@Z1HLxyKc4M++QMwnTk#^U^bq3?PX0xlMnW#aEFCxRbe3HC6lK3~ z4u`$oh4t(+pLqQc+^(j#aT2#63*U=Fi`!D)^1Cxe9I#uzW6j@U9mO{nX6P17zI~08 zGvF-G*$?t63R8}6a1s^(rW4f?*NBpo#FA92 zscm3nWnj>tmJUpFNE&kUQ!>*kaclTkeg6kggCxj?;QX|b^2DN4hVt@qz0ADq;^f4F ZRK5J7^x5xhq=1STJYD@<);T3K0RSn9HfI0; literal 0 HcmV?d00001 diff --git a/resources/icons/ui/volume-off-indicator@2x.png b/resources/icons/ui/volume-off-indicator@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..25ebbbbe27d135ee77b3dfa91529b5cd73a31fb0 GIT binary patch literal 1254 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I0wfs{c7_5;mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VW5SkEalYac}QU?;Kx8i31<& zr*efZTKbjes)ARiM~KQL7DXj36)`#O{uTjl?#|XD$CxzDk`xs;3Us<`*eIaX(z>8( z{iJP<(QCUd-3zGYkmVMid)(5v`2EiByH{WSnYQo#T;uX{i+BF%v{`q_UHRoP!Cx;v zyq|X5m*wvoZ|MmR7Y;?PI`LIkU*OATGo}Oc{grP^JPVIgc#*s{{9tAyL!-huwci4! zLE?`3+P0_6TbWpzmh14yrzjOJJzc(P&S`FKhYP3m;+^=lWlryAU}-x28gRVA-buWB>ts=22>LwQ*7#w@!-p+ZOAm{SX<7=eC}widOXq1> zys(z1#ZSwLW800x{Hc57Z>`Y^TqI~`7=KdpQL8e;Hlr0i;>zczf0$S)weXrCL;Kdt z1$VA3Z3*|9&i72qvh|7;(}OwNZ2iBeZ!wNmwz>Z7sEqQKz29cUt`)weahaoNPip#s zjH!QurhU_}P83=%>ZHANp{)?dJC-MNLXX`_XP?1w_RIzbme^ZWj2Z#oj=43+=oza| z30N`rXWFU^UX~v3d0k$1*=tQ@CiR`JJiGt?=JU^eAC$iRUtV*>W9`t{O^$`PS>LsgPUicraq*wk7d6xQd!v5WzFg68 z>PotU!iwv822Z-bvLBxJKTayK{FO07z`58|@3$$UAM4#GM=t(asUR!5oV|fntZAS8 zmJ`O)^cb|9I8&qQ(zh5VD5tOrxNTrO=ElsS)^pM5srnNCK*lBxL*4vUC0E2`5BS{3 zVcg=*X&_i-WY1jq(nEcP;(gyOOSg-1w|rZo($OmLNpeEb^QHU;x&zjxh`BI+P@FS; z(=A1*2J3~9r*;a+9++AXb?OF(We$I&(dnB>e?_10DBcN`OMbj2XxqJo=F6BxKHAoN zNQ^0&$M`+cVrtIrl)puOEI|r$Tt1xs@n!;(Bd_@(&UHJdZWsPipe%BWd$*v^!|m3~ zJPq8%I2|XNIu)dJ3WyoMJZqz9VI~nD>+WZ8++-d5zdR+i7l8*^b6**IOjtat`r2yu zBP^CejjHU%t_6%WY3x@|-Azbgv3}sSDWHwxVMEw8{>-bKrgl%yv?LtxKNq-Q%juTc z+qOUZH_=0HNBbM|J&uz&B{lf(+B^*SQGa|=OV5<{mwu5~V}3{fGr#F4P`oc5!lIL8@MUQTpt6Hc~)E44$rjF6*2U FngA4b`Skz* literal 0 HcmV?d00001 diff --git a/resources/res.qrc b/resources/res.qrc index 71463e65..8484b299 100644 --- a/resources/res.qrc +++ b/resources/res.qrc @@ -1,5 +1,14 @@ + icons/ui/volume-off-indicator.png + icons/ui/volume-off-indicator@2x.png + icons/ui/black-bubble-speech.png + icons/ui/black-bubble-speech@2x.png + icons/ui/do-not-disturb-rounded-sign.png + icons/ui/do-not-disturb-rounded-sign@2x.png + icons/ui/round-remove-button.png + icons/ui/round-remove-button@2x.png + icons/ui/double-tick-indicator.png icons/ui/double-tick-indicator@2x.png icons/ui/lock.png diff --git a/resources/styles/nheko-dark.qss b/resources/styles/nheko-dark.qss index c95eca2f..2729343c 100644 --- a/resources/styles/nheko-dark.qss +++ b/resources/styles/nheko-dark.qss @@ -147,6 +147,7 @@ dialogs--ReadReceipts, dialogs--JoinRoom, dialogs--MemberList, dialogs--PreviewUploadOverlay, +dialogs--UserProfile, dialogs--CreateRoom > QLineEdit, dialogs--InviteUsers > QLineEdit, EditModal, diff --git a/resources/styles/nheko.qss b/resources/styles/nheko.qss index 674d1722..163832bd 100644 --- a/resources/styles/nheko.qss +++ b/resources/styles/nheko.qss @@ -149,10 +149,11 @@ dialogs--ReadReceipts, dialogs--MemberList, dialogs--JoinRoom, dialogs--PreviewUploadOverlay, +dialogs--UserProfile, EditModal, QListWidget { background-color: white; - color: #333; + color: #495057; } TopSection { diff --git a/src/AvatarProvider.cpp b/src/AvatarProvider.cpp index dbfc1945..57b61c75 100644 --- a/src/AvatarProvider.cpp +++ b/src/AvatarProvider.cpp @@ -50,6 +50,8 @@ resolve(const QString &room_id, const QString &user_id, QObject *receiver, Avata [callback](const QByteArray &data) { callback(QImage::fromData(data)); }); mtx::http::ThumbOpts opts; + opts.width = 256; + opts.height = 256; opts.mxc_url = avatarUrl.toStdString(); http::client()->get_thumbnail( diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index fdca98c3..35bfba86 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -309,6 +309,18 @@ MainWindow::hasActiveUser() settings.contains("auth/user_id"); } +void +MainWindow::openUserProfile(const QString &user_id, const QString &room_id) +{ + userProfileDialog_ = QSharedPointer(new dialogs::UserProfile(this)); + userProfileDialog_->init(user_id, room_id); + + userProfileModal_ = + QSharedPointer(new OverlayModal(this, userProfileDialog_.data())); + + userProfileModal_->show(); +} + void MainWindow::openRoomSettings(const QString &room_id) { @@ -382,6 +394,7 @@ MainWindow::showOverlayProgressBar() progressModal_ = QSharedPointer(new OverlayModal(this, spinner_.data()), [](OverlayModal *modal) { modal->deleteLater(); }); + progressModal_->setContentAlignment(Qt::AlignCenter); progressModal_->setColor(QColor(30, 30, 30)); progressModal_->setDismissible(false); progressModal_->show(); diff --git a/src/MainWindow.h b/src/MainWindow.h index 92040191..3d9a94d3 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -28,6 +28,7 @@ #include "RegisterPage.h" #include "UserSettingsPage.h" #include "WelcomePage.h" +#include "dialogs/UserProfile.h" class ChatPage; class LoadingIndicator; @@ -71,6 +72,7 @@ public: void openLogoutDialog(std::function callback); void openRoomSettings(const QString &room_id = ""); void openMemberListDialog(const QString &room_id = ""); + void openUserProfile(const QString &user_id, const QString &room_id); protected: void closeEvent(QCloseEvent *event) override; @@ -171,4 +173,7 @@ private: QSharedPointer memberListModal_; //! Member list dialog. QSharedPointer memberListDialog_; + + QSharedPointer userProfileModal_; + QSharedPointer userProfileDialog_; }; diff --git a/src/dialogs/UserProfile.cpp b/src/dialogs/UserProfile.cpp new file mode 100644 index 00000000..1da293a5 --- /dev/null +++ b/src/dialogs/UserProfile.cpp @@ -0,0 +1,153 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "AvatarProvider.h" +#include "Cache.h" +#include "Utils.h" +#include "dialogs/UserProfile.h" +#include "ui/Avatar.h" +#include "ui/FlatButton.h" + +using namespace dialogs; + +constexpr int BUTTON_SIZE = 36; + +DeviceItem::DeviceItem(QWidget *parent, QString deviceName) + : QWidget(parent) + , name_(deviceName) +{} + +UserProfile::UserProfile(QWidget *parent) + : QWidget(parent) +{ + QIcon banIcon, kickIcon, ignoreIcon, startChatIcon; + + banIcon.addFile(":/icons/icons/ui/do-not-disturb-rounded-sign.png"); + banBtn_ = new FlatButton(this); + banBtn_->setFixedSize(BUTTON_SIZE, BUTTON_SIZE); + banBtn_->setCornerRadius(BUTTON_SIZE / 2); + banBtn_->setIcon(banIcon); + banBtn_->setIconSize(QSize(BUTTON_SIZE / 2, BUTTON_SIZE / 2)); + banBtn_->setToolTip(tr("Ban the user from the room")); + + ignoreIcon.addFile(":/icons/icons/ui/volume-off-indicator.png"); + ignoreBtn_ = new FlatButton(this); + ignoreBtn_->setFixedSize(BUTTON_SIZE, BUTTON_SIZE); + ignoreBtn_->setCornerRadius(BUTTON_SIZE / 2); + ignoreBtn_->setIcon(ignoreIcon); + ignoreBtn_->setIconSize(QSize(BUTTON_SIZE / 2, BUTTON_SIZE / 2)); + ignoreBtn_->setToolTip(tr("Ignore messages from this user")); + + kickIcon.addFile(":/icons/icons/ui/round-remove-button.png"); + kickBtn_ = new FlatButton(this); + kickBtn_->setFixedSize(BUTTON_SIZE, BUTTON_SIZE); + kickBtn_->setCornerRadius(BUTTON_SIZE / 2); + kickBtn_->setIcon(kickIcon); + kickBtn_->setIconSize(QSize(BUTTON_SIZE / 2, BUTTON_SIZE / 2)); + kickBtn_->setToolTip(tr("Kick the user from the room")); + + startChatIcon.addFile(":/icons/icons/ui/black-bubble-speech.png"); + startChat_ = new FlatButton(this); + startChat_->setFixedSize(BUTTON_SIZE, BUTTON_SIZE); + startChat_->setCornerRadius(BUTTON_SIZE / 2); + startChat_->setIcon(startChatIcon); + startChat_->setIconSize(QSize(BUTTON_SIZE / 2, BUTTON_SIZE / 2)); + startChat_->setToolTip(tr("Start a conversation")); + + // Button line + auto btnLayout = new QHBoxLayout; + btnLayout->addWidget(startChat_); + btnLayout->addWidget(ignoreBtn_); + + // TODO: check if the user has enough power level given the room_id + // in which the profile was opened. + btnLayout->addWidget(kickBtn_); + btnLayout->addWidget(banBtn_); + btnLayout->setSpacing(8); + btnLayout->setMargin(0); + + avatar_ = new Avatar(this); + avatar_->setLetter("X"); + avatar_->setSize(148); + + QFont font; + font.setPointSizeF(font.pointSizeF() * 2); + + userIdLabel_ = new QLabel(this); + displayNameLabel_ = new QLabel(this); + displayNameLabel_->setFont(font); + + auto textLayout = new QVBoxLayout; + textLayout->addWidget(displayNameLabel_); + textLayout->addWidget(userIdLabel_); + textLayout->setAlignment(displayNameLabel_, Qt::AlignCenter | Qt::AlignTop); + textLayout->setAlignment(userIdLabel_, Qt::AlignCenter | Qt::AlignTop); + textLayout->setSpacing(4); + textLayout->setMargin(0); + + auto vlayout = new QVBoxLayout{this}; + vlayout->addWidget(avatar_); + vlayout->addLayout(textLayout); + vlayout->addLayout(btnLayout); + + vlayout->setAlignment(avatar_, Qt::AlignCenter | Qt::AlignTop); + vlayout->setAlignment(userIdLabel_, Qt::AlignCenter | Qt::AlignTop); + + setAutoFillBackground(true); + setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); + setWindowModality(Qt::WindowModal); + + setMinimumWidth(340); + setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); + + vlayout->setSpacing(15); + vlayout->setContentsMargins(20, 40, 20, 20); +} + +void +UserProfile::init(const QString &userId, const QString &roomId) +{ + auto displayName = Cache::displayName(roomId, userId); + + userIdLabel_->setText(userId); + displayNameLabel_->setText(displayName); + avatar_->setLetter(utils::firstChar(displayName)); + + AvatarProvider::resolve( + roomId, userId, this, [this](const QImage &img) { avatar_->setImage(img); }); + + QSettings settings; + auto localUser = settings.value("auth/user_id").toString(); + + if (localUser == userId) { + qDebug() << "the local user should have edit rights on avatar & display name"; + // TODO: click on display name & avatar to change. + } + + try { + bool hasMemberRights = + cache::client()->hasEnoughPowerLevel({mtx::events::EventType::RoomMember}, + roomId.toStdString(), + localUser.toStdString()); + if (!hasMemberRights) { + kickBtn_->hide(); + banBtn_->hide(); + } + } catch (const lmdb::error &e) { + nhlog::db()->warn("lmdb error: {}", e.what()); + } +} + +void +UserProfile::paintEvent(QPaintEvent *) +{ + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); +} diff --git a/src/dialogs/UserProfile.h b/src/dialogs/UserProfile.h new file mode 100644 index 00000000..8d5b9c5f --- /dev/null +++ b/src/dialogs/UserProfile.h @@ -0,0 +1,53 @@ +#pragma once + +#include +#include + +class Avatar; +class FlatButton; +class QLabel; +class QListWidget; + +namespace dialogs { + +class DeviceItem : public QWidget +{ + Q_OBJECT + +public: + explicit DeviceItem(QWidget *parent, QString deviceName); + +private: + QString name_; + + // Toggle *verifyToggle_; +}; + +class UserProfile : public QWidget +{ + Q_OBJECT +public: + explicit UserProfile(QWidget *parent = nullptr); + + void init(const QString &userId, const QString &roomId); + +protected: + void paintEvent(QPaintEvent *) override; + +private: + Avatar *avatar_; + + QString displayName_; + QString userId_; + + QLabel *userIdLabel_; + QLabel *displayNameLabel_; + + FlatButton *banBtn_; + FlatButton *kickBtn_; + FlatButton *ignoreBtn_; + FlatButton *startChat_; + + QListWidget *devices_; +}; +} // dialogs diff --git a/src/timeline/TimelineItem.cpp b/src/timeline/TimelineItem.cpp index 696db8de..71b3156c 100644 --- a/src/timeline/TimelineItem.cpp +++ b/src/timeline/TimelineItem.cpp @@ -23,6 +23,7 @@ #include "ChatPage.h" #include "Config.h" #include "Logging.h" +#include "MainWindow.h" #include "Olm.h" #include "ui/Avatar.h" #include "ui/Painter.h" @@ -561,6 +562,13 @@ TimelineItem::generateBody(const QString &body) // The username/timestamp is displayed along with the message body. void TimelineItem::generateBody(const QString &user_id, const QString &displayname, const QString &body) +{ + generateUserName(user_id, displayname); + generateBody(body); +} + +void +TimelineItem::generateUserName(const QString &user_id, const QString &displayname) { auto sender = displayname; @@ -598,7 +606,9 @@ TimelineItem::generateBody(const QString &user_id, const QString &displayname, c userName_->setFont(f); }); - generateBody(body); + connect(filter, &UserProfileFilter::clicked, this, [this, user_id]() { + MainWindow::instance()->openUserProfile(user_id, room_id_); + }); } void @@ -742,10 +752,7 @@ TimelineItem::addAvatar() auto userid = descriptionMsg_.userid; auto displayName = Cache::displayName(room_id_, userid); - QFontMetrics fm(usernameFont_); - userName_ = new QLabel(this); - userName_->setFont(usernameFont_); - userName_->setText(fm.elidedText(displayName, Qt::ElideRight, 500)); + generateUserName(userid, displayName); setupAvatarLayout(displayName); diff --git a/src/timeline/TimelineItem.h b/src/timeline/TimelineItem.h index 874c00df..db000078 100644 --- a/src/timeline/TimelineItem.h +++ b/src/timeline/TimelineItem.h @@ -137,13 +137,13 @@ public: signals: void hoverOff(); void hoverOn(); + void clicked(); protected: bool eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::MouseButtonRelease) { - // QMouseEvent *mouseEvent = static_cast(event); - // TODO: Open user profile + emit clicked(); return true; } else if (event->type() == QEvent::HoverLeave) { emit hoverOff(); @@ -274,6 +274,7 @@ private: void generateBody(const QString &body); void generateBody(const QString &user_id, const QString &displayname, const QString &body); void generateTimestamp(const QDateTime &time); + void generateUserName(const QString &userid, const QString &displayname); void setupAvatarLayout(const QString &userName); void setupSimpleLayout(); diff --git a/src/ui/OverlayModal.cpp b/src/ui/OverlayModal.cpp index 6aa16b07..41e07a91 100644 --- a/src/ui/OverlayModal.cpp +++ b/src/ui/OverlayModal.cpp @@ -25,11 +25,11 @@ OverlayModal::OverlayModal(QWidget *parent, QWidget *content) , content_{content} , color_{QColor(30, 30, 30, 170)} { - auto layout = new QVBoxLayout(); - layout->addWidget(content); - layout->setAlignment(Qt::AlignCenter); - - setLayout(layout); + layout_ = new QVBoxLayout(this); + layout_->addWidget(content); + layout_->setSpacing(0); + layout_->setContentsMargins(10, 40, 10, 20); + setContentAlignment(Qt::AlignTop | Qt::AlignHCenter); content->setFocus(); } diff --git a/src/ui/OverlayModal.h b/src/ui/OverlayModal.h index a761e3ed..acba7a7a 100644 --- a/src/ui/OverlayModal.h +++ b/src/ui/OverlayModal.h @@ -20,6 +20,7 @@ #include #include #include +#include #include "OverlayWidget.h" @@ -31,6 +32,8 @@ public: void setColor(QColor color) { color_ = color; } void setDismissible(bool state) { isDismissible_ = state; } + void setContentAlignment(QFlags flag) { layout_->setAlignment(flag); } + protected: void paintEvent(QPaintEvent *event) override; void keyPressEvent(QKeyEvent *event) override; @@ -38,6 +41,8 @@ protected: private: QWidget *content_; + QVBoxLayout *layout_; + QColor color_; //! Decides whether or not the modal can be removed by clicking into it.