diff --git a/res/flags/AD.png b/res/flags/AD.png deleted file mode 100644 index d5d59645fe..0000000000 Binary files a/res/flags/AD.png and /dev/null differ diff --git a/res/flags/AE.png b/res/flags/AE.png deleted file mode 100644 index 05c7418aa4..0000000000 Binary files a/res/flags/AE.png and /dev/null differ diff --git a/res/flags/AF.png b/res/flags/AF.png deleted file mode 100644 index bc7cef0916..0000000000 Binary files a/res/flags/AF.png and /dev/null differ diff --git a/res/flags/AG.png b/res/flags/AG.png deleted file mode 100644 index d48facad47..0000000000 Binary files a/res/flags/AG.png and /dev/null differ diff --git a/res/flags/AI.png b/res/flags/AI.png deleted file mode 100644 index 8fd27cd39e..0000000000 Binary files a/res/flags/AI.png and /dev/null differ diff --git a/res/flags/AL.png b/res/flags/AL.png deleted file mode 100644 index 883835ffb3..0000000000 Binary files a/res/flags/AL.png and /dev/null differ diff --git a/res/flags/AM.png b/res/flags/AM.png deleted file mode 100644 index b1bb36b987..0000000000 Binary files a/res/flags/AM.png and /dev/null differ diff --git a/res/flags/AO.png b/res/flags/AO.png deleted file mode 100644 index ae68b12c44..0000000000 Binary files a/res/flags/AO.png and /dev/null differ diff --git a/res/flags/AQ.png b/res/flags/AQ.png deleted file mode 100644 index 146e9c0a04..0000000000 Binary files a/res/flags/AQ.png and /dev/null differ diff --git a/res/flags/AR.png b/res/flags/AR.png deleted file mode 100644 index 8142adfc83..0000000000 Binary files a/res/flags/AR.png and /dev/null differ diff --git a/res/flags/AS.png b/res/flags/AS.png deleted file mode 100644 index cc5bf30daf..0000000000 Binary files a/res/flags/AS.png and /dev/null differ diff --git a/res/flags/AT.png b/res/flags/AT.png deleted file mode 100644 index e32414bd6a..0000000000 Binary files a/res/flags/AT.png and /dev/null differ diff --git a/res/flags/AU.png b/res/flags/AU.png deleted file mode 100644 index 8d1e143791..0000000000 Binary files a/res/flags/AU.png and /dev/null differ diff --git a/res/flags/AW.png b/res/flags/AW.png deleted file mode 100644 index 6ec178847e..0000000000 Binary files a/res/flags/AW.png and /dev/null differ diff --git a/res/flags/AX.png b/res/flags/AX.png deleted file mode 100644 index ba269c0453..0000000000 Binary files a/res/flags/AX.png and /dev/null differ diff --git a/res/flags/AZ.png b/res/flags/AZ.png deleted file mode 100644 index 2bf3c746e7..0000000000 Binary files a/res/flags/AZ.png and /dev/null differ diff --git a/res/flags/BA.png b/res/flags/BA.png deleted file mode 100644 index 3e3ec3fc76..0000000000 Binary files a/res/flags/BA.png and /dev/null differ diff --git a/res/flags/BB.png b/res/flags/BB.png deleted file mode 100644 index 694050ca46..0000000000 Binary files a/res/flags/BB.png and /dev/null differ diff --git a/res/flags/BD.png b/res/flags/BD.png deleted file mode 100644 index 6de2cde85b..0000000000 Binary files a/res/flags/BD.png and /dev/null differ diff --git a/res/flags/BE.png b/res/flags/BE.png deleted file mode 100644 index 742ba9231f..0000000000 Binary files a/res/flags/BE.png and /dev/null differ diff --git a/res/flags/BF.png b/res/flags/BF.png deleted file mode 100644 index 17f9f67d26..0000000000 Binary files a/res/flags/BF.png and /dev/null differ diff --git a/res/flags/BG.png b/res/flags/BG.png deleted file mode 100644 index b01d3ff57b..0000000000 Binary files a/res/flags/BG.png and /dev/null differ diff --git a/res/flags/BH.png b/res/flags/BH.png deleted file mode 100644 index d0f82e8285..0000000000 Binary files a/res/flags/BH.png and /dev/null differ diff --git a/res/flags/BI.png b/res/flags/BI.png deleted file mode 100644 index 21865ac720..0000000000 Binary files a/res/flags/BI.png and /dev/null differ diff --git a/res/flags/BJ.png b/res/flags/BJ.png deleted file mode 100644 index a7c6091434..0000000000 Binary files a/res/flags/BJ.png and /dev/null differ diff --git a/res/flags/BL.png b/res/flags/BL.png deleted file mode 100644 index 6d50a0f544..0000000000 Binary files a/res/flags/BL.png and /dev/null differ diff --git a/res/flags/BM.png b/res/flags/BM.png deleted file mode 100644 index 310a25ea23..0000000000 Binary files a/res/flags/BM.png and /dev/null differ diff --git a/res/flags/BN.png b/res/flags/BN.png deleted file mode 100644 index bc4da8d9a6..0000000000 Binary files a/res/flags/BN.png and /dev/null differ diff --git a/res/flags/BO.png b/res/flags/BO.png deleted file mode 100644 index 144b8d32db..0000000000 Binary files a/res/flags/BO.png and /dev/null differ diff --git a/res/flags/BQ.png b/res/flags/BQ.png deleted file mode 100644 index 0897943760..0000000000 Binary files a/res/flags/BQ.png and /dev/null differ diff --git a/res/flags/BR.png b/res/flags/BR.png deleted file mode 100644 index 0278492592..0000000000 Binary files a/res/flags/BR.png and /dev/null differ diff --git a/res/flags/BS.png b/res/flags/BS.png deleted file mode 100644 index 2b05a8fc7c..0000000000 Binary files a/res/flags/BS.png and /dev/null differ diff --git a/res/flags/BT.png b/res/flags/BT.png deleted file mode 100644 index 1f031df071..0000000000 Binary files a/res/flags/BT.png and /dev/null differ diff --git a/res/flags/BV.png b/res/flags/BV.png deleted file mode 100644 index aafb0f1776..0000000000 Binary files a/res/flags/BV.png and /dev/null differ diff --git a/res/flags/BW.png b/res/flags/BW.png deleted file mode 100644 index 3084016718..0000000000 Binary files a/res/flags/BW.png and /dev/null differ diff --git a/res/flags/BY.png b/res/flags/BY.png deleted file mode 100644 index ce9de9c9c7..0000000000 Binary files a/res/flags/BY.png and /dev/null differ diff --git a/res/flags/BZ.png b/res/flags/BZ.png deleted file mode 100644 index 33620c3f31..0000000000 Binary files a/res/flags/BZ.png and /dev/null differ diff --git a/res/flags/CA.png b/res/flags/CA.png deleted file mode 100644 index 4bbf8b1169..0000000000 Binary files a/res/flags/CA.png and /dev/null differ diff --git a/res/flags/CC.png b/res/flags/CC.png deleted file mode 100644 index fd40fc8a78..0000000000 Binary files a/res/flags/CC.png and /dev/null differ diff --git a/res/flags/CD.png b/res/flags/CD.png deleted file mode 100644 index 230aacd454..0000000000 Binary files a/res/flags/CD.png and /dev/null differ diff --git a/res/flags/CF.png b/res/flags/CF.png deleted file mode 100644 index c58ed4f7b2..0000000000 Binary files a/res/flags/CF.png and /dev/null differ diff --git a/res/flags/CG.png b/res/flags/CG.png deleted file mode 100644 index 6c2441e3e0..0000000000 Binary files a/res/flags/CG.png and /dev/null differ diff --git a/res/flags/CH.png b/res/flags/CH.png deleted file mode 100644 index 9fd87167df..0000000000 Binary files a/res/flags/CH.png and /dev/null differ diff --git a/res/flags/CI.png b/res/flags/CI.png deleted file mode 100644 index 9741b9b11f..0000000000 Binary files a/res/flags/CI.png and /dev/null differ diff --git a/res/flags/CK.png b/res/flags/CK.png deleted file mode 100644 index 6cca35967c..0000000000 Binary files a/res/flags/CK.png and /dev/null differ diff --git a/res/flags/CL.png b/res/flags/CL.png deleted file mode 100644 index 13b993d15d..0000000000 Binary files a/res/flags/CL.png and /dev/null differ diff --git a/res/flags/CM.png b/res/flags/CM.png deleted file mode 100644 index bca5730fb5..0000000000 Binary files a/res/flags/CM.png and /dev/null differ diff --git a/res/flags/CN.png b/res/flags/CN.png deleted file mode 100644 index e086855c73..0000000000 Binary files a/res/flags/CN.png and /dev/null differ diff --git a/res/flags/CO.png b/res/flags/CO.png deleted file mode 100644 index 65c0aba447..0000000000 Binary files a/res/flags/CO.png and /dev/null differ diff --git a/res/flags/CR.png b/res/flags/CR.png deleted file mode 100644 index b351c67a53..0000000000 Binary files a/res/flags/CR.png and /dev/null differ diff --git a/res/flags/CU.png b/res/flags/CU.png deleted file mode 100644 index e7a25c60b3..0000000000 Binary files a/res/flags/CU.png and /dev/null differ diff --git a/res/flags/CV.png b/res/flags/CV.png deleted file mode 100644 index f249bbaa46..0000000000 Binary files a/res/flags/CV.png and /dev/null differ diff --git a/res/flags/CW.png b/res/flags/CW.png deleted file mode 100644 index e02cacd3dd..0000000000 Binary files a/res/flags/CW.png and /dev/null differ diff --git a/res/flags/CX.png b/res/flags/CX.png deleted file mode 100644 index 3ea21422f0..0000000000 Binary files a/res/flags/CX.png and /dev/null differ diff --git a/res/flags/CY.png b/res/flags/CY.png deleted file mode 100644 index 3182f48bd2..0000000000 Binary files a/res/flags/CY.png and /dev/null differ diff --git a/res/flags/CZ.png b/res/flags/CZ.png deleted file mode 100644 index 5462334638..0000000000 Binary files a/res/flags/CZ.png and /dev/null differ diff --git a/res/flags/DE.png b/res/flags/DE.png deleted file mode 100644 index 93e269166b..0000000000 Binary files a/res/flags/DE.png and /dev/null differ diff --git a/res/flags/DJ.png b/res/flags/DJ.png deleted file mode 100644 index 243bb7390d..0000000000 Binary files a/res/flags/DJ.png and /dev/null differ diff --git a/res/flags/DK.png b/res/flags/DK.png deleted file mode 100644 index fc74cc396c..0000000000 Binary files a/res/flags/DK.png and /dev/null differ diff --git a/res/flags/DM.png b/res/flags/DM.png deleted file mode 100644 index c3a0e9d102..0000000000 Binary files a/res/flags/DM.png and /dev/null differ diff --git a/res/flags/DO.png b/res/flags/DO.png deleted file mode 100644 index 5c4a004fef..0000000000 Binary files a/res/flags/DO.png and /dev/null differ diff --git a/res/flags/DZ.png b/res/flags/DZ.png deleted file mode 100644 index 1589d0cc40..0000000000 Binary files a/res/flags/DZ.png and /dev/null differ diff --git a/res/flags/EC.png b/res/flags/EC.png deleted file mode 100644 index 4c53dead1c..0000000000 Binary files a/res/flags/EC.png and /dev/null differ diff --git a/res/flags/EE.png b/res/flags/EE.png deleted file mode 100644 index 3668de7919..0000000000 Binary files a/res/flags/EE.png and /dev/null differ diff --git a/res/flags/EG.png b/res/flags/EG.png deleted file mode 100644 index 66ec709df7..0000000000 Binary files a/res/flags/EG.png and /dev/null differ diff --git a/res/flags/EH.png b/res/flags/EH.png deleted file mode 100644 index 148be93c08..0000000000 Binary files a/res/flags/EH.png and /dev/null differ diff --git a/res/flags/ER.png b/res/flags/ER.png deleted file mode 100644 index 7cb8441514..0000000000 Binary files a/res/flags/ER.png and /dev/null differ diff --git a/res/flags/ES.png b/res/flags/ES.png deleted file mode 100644 index aae73b6fcb..0000000000 Binary files a/res/flags/ES.png and /dev/null differ diff --git a/res/flags/ET.png b/res/flags/ET.png deleted file mode 100644 index 7b420f02f4..0000000000 Binary files a/res/flags/ET.png and /dev/null differ diff --git a/res/flags/FI.png b/res/flags/FI.png deleted file mode 100644 index 42f64bf360..0000000000 Binary files a/res/flags/FI.png and /dev/null differ diff --git a/res/flags/FJ.png b/res/flags/FJ.png deleted file mode 100644 index cecc683c9c..0000000000 Binary files a/res/flags/FJ.png and /dev/null differ diff --git a/res/flags/FK.png b/res/flags/FK.png deleted file mode 100644 index 6074fea09c..0000000000 Binary files a/res/flags/FK.png and /dev/null differ diff --git a/res/flags/FM.png b/res/flags/FM.png deleted file mode 100644 index 45fdb66426..0000000000 Binary files a/res/flags/FM.png and /dev/null differ diff --git a/res/flags/FO.png b/res/flags/FO.png deleted file mode 100644 index d8fd75c638..0000000000 Binary files a/res/flags/FO.png and /dev/null differ diff --git a/res/flags/FR.png b/res/flags/FR.png deleted file mode 100644 index 6d50a0f544..0000000000 Binary files a/res/flags/FR.png and /dev/null differ diff --git a/res/flags/GA.png b/res/flags/GA.png deleted file mode 100644 index 3808a61f1d..0000000000 Binary files a/res/flags/GA.png and /dev/null differ diff --git a/res/flags/GB.png b/res/flags/GB.png deleted file mode 100644 index 589be70063..0000000000 Binary files a/res/flags/GB.png and /dev/null differ diff --git a/res/flags/GD.png b/res/flags/GD.png deleted file mode 100644 index babe1e4cc6..0000000000 Binary files a/res/flags/GD.png and /dev/null differ diff --git a/res/flags/GE.png b/res/flags/GE.png deleted file mode 100644 index d34cddeca9..0000000000 Binary files a/res/flags/GE.png and /dev/null differ diff --git a/res/flags/GF.png b/res/flags/GF.png deleted file mode 100644 index 98828a5906..0000000000 Binary files a/res/flags/GF.png and /dev/null differ diff --git a/res/flags/GG.png b/res/flags/GG.png deleted file mode 100644 index aec8969b28..0000000000 Binary files a/res/flags/GG.png and /dev/null differ diff --git a/res/flags/GH.png b/res/flags/GH.png deleted file mode 100644 index 70b1a623de..0000000000 Binary files a/res/flags/GH.png and /dev/null differ diff --git a/res/flags/GI.png b/res/flags/GI.png deleted file mode 100644 index 9aa58327e3..0000000000 Binary files a/res/flags/GI.png and /dev/null differ diff --git a/res/flags/GL.png b/res/flags/GL.png deleted file mode 100644 index cf1645c2b5..0000000000 Binary files a/res/flags/GL.png and /dev/null differ diff --git a/res/flags/GM.png b/res/flags/GM.png deleted file mode 100644 index ec374fb3c3..0000000000 Binary files a/res/flags/GM.png and /dev/null differ diff --git a/res/flags/GN.png b/res/flags/GN.png deleted file mode 100644 index 46874b4d98..0000000000 Binary files a/res/flags/GN.png and /dev/null differ diff --git a/res/flags/GP.png b/res/flags/GP.png deleted file mode 100644 index 81b7abdf0e..0000000000 Binary files a/res/flags/GP.png and /dev/null differ diff --git a/res/flags/GQ.png b/res/flags/GQ.png deleted file mode 100644 index 7fd1015e8b..0000000000 Binary files a/res/flags/GQ.png and /dev/null differ diff --git a/res/flags/GR.png b/res/flags/GR.png deleted file mode 100644 index 101de51eab..0000000000 Binary files a/res/flags/GR.png and /dev/null differ diff --git a/res/flags/GS.png b/res/flags/GS.png deleted file mode 100644 index 772c2cbe6d..0000000000 Binary files a/res/flags/GS.png and /dev/null differ diff --git a/res/flags/GT.png b/res/flags/GT.png deleted file mode 100644 index d5bd8c1e46..0000000000 Binary files a/res/flags/GT.png and /dev/null differ diff --git a/res/flags/GU.png b/res/flags/GU.png deleted file mode 100644 index 8923085d5a..0000000000 Binary files a/res/flags/GU.png and /dev/null differ diff --git a/res/flags/GW.png b/res/flags/GW.png deleted file mode 100644 index 20c268ce06..0000000000 Binary files a/res/flags/GW.png and /dev/null differ diff --git a/res/flags/GY.png b/res/flags/GY.png deleted file mode 100644 index 86f56635ef..0000000000 Binary files a/res/flags/GY.png and /dev/null differ diff --git a/res/flags/HK.png b/res/flags/HK.png deleted file mode 100644 index 907dc59624..0000000000 Binary files a/res/flags/HK.png and /dev/null differ diff --git a/res/flags/HM.png b/res/flags/HM.png deleted file mode 100644 index 8d1e143791..0000000000 Binary files a/res/flags/HM.png and /dev/null differ diff --git a/res/flags/HN.png b/res/flags/HN.png deleted file mode 100644 index 4cf8c3112c..0000000000 Binary files a/res/flags/HN.png and /dev/null differ diff --git a/res/flags/HR.png b/res/flags/HR.png deleted file mode 100644 index 413ceb1586..0000000000 Binary files a/res/flags/HR.png and /dev/null differ diff --git a/res/flags/HT.png b/res/flags/HT.png deleted file mode 100644 index 097abeb434..0000000000 Binary files a/res/flags/HT.png and /dev/null differ diff --git a/res/flags/HU.png b/res/flags/HU.png deleted file mode 100644 index 23499bf63c..0000000000 Binary files a/res/flags/HU.png and /dev/null differ diff --git a/res/flags/ID.png b/res/flags/ID.png deleted file mode 100644 index 80200657c6..0000000000 Binary files a/res/flags/ID.png and /dev/null differ diff --git a/res/flags/IE.png b/res/flags/IE.png deleted file mode 100644 index 63f2220118..0000000000 Binary files a/res/flags/IE.png and /dev/null differ diff --git a/res/flags/IL.png b/res/flags/IL.png deleted file mode 100644 index 0268826321..0000000000 Binary files a/res/flags/IL.png and /dev/null differ diff --git a/res/flags/IM.png b/res/flags/IM.png deleted file mode 100644 index c777acc490..0000000000 Binary files a/res/flags/IM.png and /dev/null differ diff --git a/res/flags/IN.png b/res/flags/IN.png deleted file mode 100644 index 85fa9bfe72..0000000000 Binary files a/res/flags/IN.png and /dev/null differ diff --git a/res/flags/IO.png b/res/flags/IO.png deleted file mode 100644 index 1675d8e7db..0000000000 Binary files a/res/flags/IO.png and /dev/null differ diff --git a/res/flags/IQ.png b/res/flags/IQ.png deleted file mode 100644 index f2c21f7260..0000000000 Binary files a/res/flags/IQ.png and /dev/null differ diff --git a/res/flags/IR.png b/res/flags/IR.png deleted file mode 100644 index 0b8e67506c..0000000000 Binary files a/res/flags/IR.png and /dev/null differ diff --git a/res/flags/IS.png b/res/flags/IS.png deleted file mode 100644 index 5ee3e63c5c..0000000000 Binary files a/res/flags/IS.png and /dev/null differ diff --git a/res/flags/IT.png b/res/flags/IT.png deleted file mode 100644 index 53b967be99..0000000000 Binary files a/res/flags/IT.png and /dev/null differ diff --git a/res/flags/JE.png b/res/flags/JE.png deleted file mode 100644 index a1437aba78..0000000000 Binary files a/res/flags/JE.png and /dev/null differ diff --git a/res/flags/JM.png b/res/flags/JM.png deleted file mode 100644 index 0d462fa3ae..0000000000 Binary files a/res/flags/JM.png and /dev/null differ diff --git a/res/flags/JO.png b/res/flags/JO.png deleted file mode 100644 index 8934db7eca..0000000000 Binary files a/res/flags/JO.png and /dev/null differ diff --git a/res/flags/JP.png b/res/flags/JP.png deleted file mode 100644 index 6f92d52365..0000000000 Binary files a/res/flags/JP.png and /dev/null differ diff --git a/res/flags/KE.png b/res/flags/KE.png deleted file mode 100644 index 866b3f15dc..0000000000 Binary files a/res/flags/KE.png and /dev/null differ diff --git a/res/flags/KG.png b/res/flags/KG.png deleted file mode 100644 index 56b433c756..0000000000 Binary files a/res/flags/KG.png and /dev/null differ diff --git a/res/flags/KH.png b/res/flags/KH.png deleted file mode 100644 index e1ddd5f84c..0000000000 Binary files a/res/flags/KH.png and /dev/null differ diff --git a/res/flags/KI.png b/res/flags/KI.png deleted file mode 100644 index 8b7c54bc0f..0000000000 Binary files a/res/flags/KI.png and /dev/null differ diff --git a/res/flags/KM.png b/res/flags/KM.png deleted file mode 100644 index 227a3b3396..0000000000 Binary files a/res/flags/KM.png and /dev/null differ diff --git a/res/flags/KN.png b/res/flags/KN.png deleted file mode 100644 index bc6189bed1..0000000000 Binary files a/res/flags/KN.png and /dev/null differ diff --git a/res/flags/KP.png b/res/flags/KP.png deleted file mode 100644 index c92248b910..0000000000 Binary files a/res/flags/KP.png and /dev/null differ diff --git a/res/flags/KR.png b/res/flags/KR.png deleted file mode 100644 index ab1cb94943..0000000000 Binary files a/res/flags/KR.png and /dev/null differ diff --git a/res/flags/KW.png b/res/flags/KW.png deleted file mode 100644 index 0b41c7a532..0000000000 Binary files a/res/flags/KW.png and /dev/null differ diff --git a/res/flags/KY.png b/res/flags/KY.png deleted file mode 100644 index 7af5290d31..0000000000 Binary files a/res/flags/KY.png and /dev/null differ diff --git a/res/flags/KZ.png b/res/flags/KZ.png deleted file mode 100644 index e10a1255a0..0000000000 Binary files a/res/flags/KZ.png and /dev/null differ diff --git a/res/flags/LA.png b/res/flags/LA.png deleted file mode 100644 index 6ad67d4255..0000000000 Binary files a/res/flags/LA.png and /dev/null differ diff --git a/res/flags/LB.png b/res/flags/LB.png deleted file mode 100644 index 865df57a42..0000000000 Binary files a/res/flags/LB.png and /dev/null differ diff --git a/res/flags/LC.png b/res/flags/LC.png deleted file mode 100644 index e83a2d08bc..0000000000 Binary files a/res/flags/LC.png and /dev/null differ diff --git a/res/flags/LI.png b/res/flags/LI.png deleted file mode 100644 index 57034d367c..0000000000 Binary files a/res/flags/LI.png and /dev/null differ diff --git a/res/flags/LK.png b/res/flags/LK.png deleted file mode 100644 index 6e7ad58254..0000000000 Binary files a/res/flags/LK.png and /dev/null differ diff --git a/res/flags/LR.png b/res/flags/LR.png deleted file mode 100644 index 46c3b84a92..0000000000 Binary files a/res/flags/LR.png and /dev/null differ diff --git a/res/flags/LS.png b/res/flags/LS.png deleted file mode 100644 index 79b505d490..0000000000 Binary files a/res/flags/LS.png and /dev/null differ diff --git a/res/flags/LT.png b/res/flags/LT.png deleted file mode 100644 index 7740cdc0a0..0000000000 Binary files a/res/flags/LT.png and /dev/null differ diff --git a/res/flags/LU.png b/res/flags/LU.png deleted file mode 100644 index 8f383e674e..0000000000 Binary files a/res/flags/LU.png and /dev/null differ diff --git a/res/flags/LV.png b/res/flags/LV.png deleted file mode 100644 index a0f36d89c4..0000000000 Binary files a/res/flags/LV.png and /dev/null differ diff --git a/res/flags/LY.png b/res/flags/LY.png deleted file mode 100644 index 2884c4c0a9..0000000000 Binary files a/res/flags/LY.png and /dev/null differ diff --git a/res/flags/MA.png b/res/flags/MA.png deleted file mode 100644 index 1f76cfc9bd..0000000000 Binary files a/res/flags/MA.png and /dev/null differ diff --git a/res/flags/MC.png b/res/flags/MC.png deleted file mode 100644 index 06fc2ad166..0000000000 Binary files a/res/flags/MC.png and /dev/null differ diff --git a/res/flags/MD.png b/res/flags/MD.png deleted file mode 100644 index 8e54c2b815..0000000000 Binary files a/res/flags/MD.png and /dev/null differ diff --git a/res/flags/ME.png b/res/flags/ME.png deleted file mode 100644 index 97424d4ec2..0000000000 Binary files a/res/flags/ME.png and /dev/null differ diff --git a/res/flags/MF.png b/res/flags/MF.png deleted file mode 100644 index 6d50a0f544..0000000000 Binary files a/res/flags/MF.png and /dev/null differ diff --git a/res/flags/MG.png b/res/flags/MG.png deleted file mode 100644 index 28bfccc9e8..0000000000 Binary files a/res/flags/MG.png and /dev/null differ diff --git a/res/flags/MH.png b/res/flags/MH.png deleted file mode 100644 index e482a65924..0000000000 Binary files a/res/flags/MH.png and /dev/null differ diff --git a/res/flags/MK.png b/res/flags/MK.png deleted file mode 100644 index 84e2e65e76..0000000000 Binary files a/res/flags/MK.png and /dev/null differ diff --git a/res/flags/ML.png b/res/flags/ML.png deleted file mode 100644 index 38fec34796..0000000000 Binary files a/res/flags/ML.png and /dev/null differ diff --git a/res/flags/MM.png b/res/flags/MM.png deleted file mode 100644 index 70a03c6b14..0000000000 Binary files a/res/flags/MM.png and /dev/null differ diff --git a/res/flags/MN.png b/res/flags/MN.png deleted file mode 100644 index 1e1bbe6089..0000000000 Binary files a/res/flags/MN.png and /dev/null differ diff --git a/res/flags/MO.png b/res/flags/MO.png deleted file mode 100644 index 3833d683e7..0000000000 Binary files a/res/flags/MO.png and /dev/null differ diff --git a/res/flags/MP.png b/res/flags/MP.png deleted file mode 100644 index 63119096b0..0000000000 Binary files a/res/flags/MP.png and /dev/null differ diff --git a/res/flags/MQ.png b/res/flags/MQ.png deleted file mode 100644 index 9cab441aec..0000000000 Binary files a/res/flags/MQ.png and /dev/null differ diff --git a/res/flags/MR.png b/res/flags/MR.png deleted file mode 100644 index c144de17f7..0000000000 Binary files a/res/flags/MR.png and /dev/null differ diff --git a/res/flags/MS.png b/res/flags/MS.png deleted file mode 100644 index 1221707042..0000000000 Binary files a/res/flags/MS.png and /dev/null differ diff --git a/res/flags/MT.png b/res/flags/MT.png deleted file mode 100644 index 7963aa618a..0000000000 Binary files a/res/flags/MT.png and /dev/null differ diff --git a/res/flags/MU.png b/res/flags/MU.png deleted file mode 100644 index d5d4d4008d..0000000000 Binary files a/res/flags/MU.png and /dev/null differ diff --git a/res/flags/MV.png b/res/flags/MV.png deleted file mode 100644 index 0f2ecb4389..0000000000 Binary files a/res/flags/MV.png and /dev/null differ diff --git a/res/flags/MW.png b/res/flags/MW.png deleted file mode 100644 index d0a5d24f55..0000000000 Binary files a/res/flags/MW.png and /dev/null differ diff --git a/res/flags/MX.png b/res/flags/MX.png deleted file mode 100644 index 096cb1111f..0000000000 Binary files a/res/flags/MX.png and /dev/null differ diff --git a/res/flags/MY.png b/res/flags/MY.png deleted file mode 100644 index 17f18ac519..0000000000 Binary files a/res/flags/MY.png and /dev/null differ diff --git a/res/flags/MZ.png b/res/flags/MZ.png deleted file mode 100644 index 66be6563c6..0000000000 Binary files a/res/flags/MZ.png and /dev/null differ diff --git a/res/flags/NA.png b/res/flags/NA.png deleted file mode 100644 index 7ecfd317c7..0000000000 Binary files a/res/flags/NA.png and /dev/null differ diff --git a/res/flags/NC.png b/res/flags/NC.png deleted file mode 100644 index 11126ade77..0000000000 Binary files a/res/flags/NC.png and /dev/null differ diff --git a/res/flags/NE.png b/res/flags/NE.png deleted file mode 100644 index d584fa8429..0000000000 Binary files a/res/flags/NE.png and /dev/null differ diff --git a/res/flags/NF.png b/res/flags/NF.png deleted file mode 100644 index c054042591..0000000000 Binary files a/res/flags/NF.png and /dev/null differ diff --git a/res/flags/NG.png b/res/flags/NG.png deleted file mode 100644 index 73aee15b3f..0000000000 Binary files a/res/flags/NG.png and /dev/null differ diff --git a/res/flags/NI.png b/res/flags/NI.png deleted file mode 100644 index fd044933e4..0000000000 Binary files a/res/flags/NI.png and /dev/null differ diff --git a/res/flags/NL.png b/res/flags/NL.png deleted file mode 100644 index 0897943760..0000000000 Binary files a/res/flags/NL.png and /dev/null differ diff --git a/res/flags/NO.png b/res/flags/NO.png deleted file mode 100644 index aafb0f1776..0000000000 Binary files a/res/flags/NO.png and /dev/null differ diff --git a/res/flags/NP.png b/res/flags/NP.png deleted file mode 100644 index 744458e17e..0000000000 Binary files a/res/flags/NP.png and /dev/null differ diff --git a/res/flags/NR.png b/res/flags/NR.png deleted file mode 100644 index 58c2afb228..0000000000 Binary files a/res/flags/NR.png and /dev/null differ diff --git a/res/flags/NU.png b/res/flags/NU.png deleted file mode 100644 index 007c99eca5..0000000000 Binary files a/res/flags/NU.png and /dev/null differ diff --git a/res/flags/NZ.png b/res/flags/NZ.png deleted file mode 100644 index 839368dd7b..0000000000 Binary files a/res/flags/NZ.png and /dev/null differ diff --git a/res/flags/OM.png b/res/flags/OM.png deleted file mode 100644 index 63a893367f..0000000000 Binary files a/res/flags/OM.png and /dev/null differ diff --git a/res/flags/PA.png b/res/flags/PA.png deleted file mode 100644 index 3515d95d37..0000000000 Binary files a/res/flags/PA.png and /dev/null differ diff --git a/res/flags/PE.png b/res/flags/PE.png deleted file mode 100644 index 58f70b8d18..0000000000 Binary files a/res/flags/PE.png and /dev/null differ diff --git a/res/flags/PF.png b/res/flags/PF.png deleted file mode 100644 index 2f33f2574f..0000000000 Binary files a/res/flags/PF.png and /dev/null differ diff --git a/res/flags/PG.png b/res/flags/PG.png deleted file mode 100644 index c796f587c6..0000000000 Binary files a/res/flags/PG.png and /dev/null differ diff --git a/res/flags/PH.png b/res/flags/PH.png deleted file mode 100644 index 0d98de0386..0000000000 Binary files a/res/flags/PH.png and /dev/null differ diff --git a/res/flags/PK.png b/res/flags/PK.png deleted file mode 100644 index 87f4e2f492..0000000000 Binary files a/res/flags/PK.png and /dev/null differ diff --git a/res/flags/PL.png b/res/flags/PL.png deleted file mode 100644 index 273869dfc6..0000000000 Binary files a/res/flags/PL.png and /dev/null differ diff --git a/res/flags/PM.png b/res/flags/PM.png deleted file mode 100644 index b74c396d92..0000000000 Binary files a/res/flags/PM.png and /dev/null differ diff --git a/res/flags/PN.png b/res/flags/PN.png deleted file mode 100644 index e34c62d598..0000000000 Binary files a/res/flags/PN.png and /dev/null differ diff --git a/res/flags/PR.png b/res/flags/PR.png deleted file mode 100644 index 8efdb91252..0000000000 Binary files a/res/flags/PR.png and /dev/null differ diff --git a/res/flags/PS.png b/res/flags/PS.png deleted file mode 100644 index 7a0cceec00..0000000000 Binary files a/res/flags/PS.png and /dev/null differ diff --git a/res/flags/PT.png b/res/flags/PT.png deleted file mode 100644 index 49e290827c..0000000000 Binary files a/res/flags/PT.png and /dev/null differ diff --git a/res/flags/PW.png b/res/flags/PW.png deleted file mode 100644 index 6cb2e1e70d..0000000000 Binary files a/res/flags/PW.png and /dev/null differ diff --git a/res/flags/PY.png b/res/flags/PY.png deleted file mode 100644 index a61c42c423..0000000000 Binary files a/res/flags/PY.png and /dev/null differ diff --git a/res/flags/QA.png b/res/flags/QA.png deleted file mode 100644 index bb091cc88c..0000000000 Binary files a/res/flags/QA.png and /dev/null differ diff --git a/res/flags/RE.png b/res/flags/RE.png deleted file mode 100644 index 6d50a0f544..0000000000 Binary files a/res/flags/RE.png and /dev/null differ diff --git a/res/flags/RO.png b/res/flags/RO.png deleted file mode 100644 index 4495d29eb0..0000000000 Binary files a/res/flags/RO.png and /dev/null differ diff --git a/res/flags/RS.png b/res/flags/RS.png deleted file mode 100644 index ebb0f28a7b..0000000000 Binary files a/res/flags/RS.png and /dev/null differ diff --git a/res/flags/RU.png b/res/flags/RU.png deleted file mode 100644 index 64532ffa58..0000000000 Binary files a/res/flags/RU.png and /dev/null differ diff --git a/res/flags/RW.png b/res/flags/RW.png deleted file mode 100644 index 64b3cfff04..0000000000 Binary files a/res/flags/RW.png and /dev/null differ diff --git a/res/flags/SA.png b/res/flags/SA.png deleted file mode 100644 index 250de6f6f5..0000000000 Binary files a/res/flags/SA.png and /dev/null differ diff --git a/res/flags/SB.png b/res/flags/SB.png deleted file mode 100644 index 5833c130eb..0000000000 Binary files a/res/flags/SB.png and /dev/null differ diff --git a/res/flags/SC.png b/res/flags/SC.png deleted file mode 100644 index ce5248f434..0000000000 Binary files a/res/flags/SC.png and /dev/null differ diff --git a/res/flags/SD.png b/res/flags/SD.png deleted file mode 100644 index d8711a83d6..0000000000 Binary files a/res/flags/SD.png and /dev/null differ diff --git a/res/flags/SE.png b/res/flags/SE.png deleted file mode 100644 index 81880931f3..0000000000 Binary files a/res/flags/SE.png and /dev/null differ diff --git a/res/flags/SG.png b/res/flags/SG.png deleted file mode 100644 index 6f00e57923..0000000000 Binary files a/res/flags/SG.png and /dev/null differ diff --git a/res/flags/SH.png b/res/flags/SH.png deleted file mode 100644 index 055dde68bc..0000000000 Binary files a/res/flags/SH.png and /dev/null differ diff --git a/res/flags/SI.png b/res/flags/SI.png deleted file mode 100644 index 9635983406..0000000000 Binary files a/res/flags/SI.png and /dev/null differ diff --git a/res/flags/SJ.png b/res/flags/SJ.png deleted file mode 100644 index aafb0f1776..0000000000 Binary files a/res/flags/SJ.png and /dev/null differ diff --git a/res/flags/SK.png b/res/flags/SK.png deleted file mode 100644 index 84c7021f0a..0000000000 Binary files a/res/flags/SK.png and /dev/null differ diff --git a/res/flags/SL.png b/res/flags/SL.png deleted file mode 100644 index c5ed199141..0000000000 Binary files a/res/flags/SL.png and /dev/null differ diff --git a/res/flags/SM.png b/res/flags/SM.png deleted file mode 100644 index 1af1ca284f..0000000000 Binary files a/res/flags/SM.png and /dev/null differ diff --git a/res/flags/SN.png b/res/flags/SN.png deleted file mode 100644 index d0b1843561..0000000000 Binary files a/res/flags/SN.png and /dev/null differ diff --git a/res/flags/SO.png b/res/flags/SO.png deleted file mode 100644 index 64e2970b9d..0000000000 Binary files a/res/flags/SO.png and /dev/null differ diff --git a/res/flags/SR.png b/res/flags/SR.png deleted file mode 100644 index b072dda835..0000000000 Binary files a/res/flags/SR.png and /dev/null differ diff --git a/res/flags/SS.png b/res/flags/SS.png deleted file mode 100644 index 83933d4521..0000000000 Binary files a/res/flags/SS.png and /dev/null differ diff --git a/res/flags/ST.png b/res/flags/ST.png deleted file mode 100644 index c102721a86..0000000000 Binary files a/res/flags/ST.png and /dev/null differ diff --git a/res/flags/SV.png b/res/flags/SV.png deleted file mode 100644 index 80de92e556..0000000000 Binary files a/res/flags/SV.png and /dev/null differ diff --git a/res/flags/SX.png b/res/flags/SX.png deleted file mode 100644 index dd52215c5d..0000000000 Binary files a/res/flags/SX.png and /dev/null differ diff --git a/res/flags/SY.png b/res/flags/SY.png deleted file mode 100644 index 78f45b7c0b..0000000000 Binary files a/res/flags/SY.png and /dev/null differ diff --git a/res/flags/SZ.png b/res/flags/SZ.png deleted file mode 100644 index 2182f4ff93..0000000000 Binary files a/res/flags/SZ.png and /dev/null differ diff --git a/res/flags/TC.png b/res/flags/TC.png deleted file mode 100644 index 3e3e19d4b3..0000000000 Binary files a/res/flags/TC.png and /dev/null differ diff --git a/res/flags/TD.png b/res/flags/TD.png deleted file mode 100644 index 753bec22b0..0000000000 Binary files a/res/flags/TD.png and /dev/null differ diff --git a/res/flags/TF.png b/res/flags/TF.png deleted file mode 100644 index 6d50a0f544..0000000000 Binary files a/res/flags/TF.png and /dev/null differ diff --git a/res/flags/TG.png b/res/flags/TG.png deleted file mode 100644 index 8501ada655..0000000000 Binary files a/res/flags/TG.png and /dev/null differ diff --git a/res/flags/TH.png b/res/flags/TH.png deleted file mode 100644 index 0c884c329e..0000000000 Binary files a/res/flags/TH.png and /dev/null differ diff --git a/res/flags/TJ.png b/res/flags/TJ.png deleted file mode 100644 index 3c9026fa0f..0000000000 Binary files a/res/flags/TJ.png and /dev/null differ diff --git a/res/flags/TK.png b/res/flags/TK.png deleted file mode 100644 index fd605749ea..0000000000 Binary files a/res/flags/TK.png and /dev/null differ diff --git a/res/flags/TL.png b/res/flags/TL.png deleted file mode 100644 index b4c834b1d6..0000000000 Binary files a/res/flags/TL.png and /dev/null differ diff --git a/res/flags/TM.png b/res/flags/TM.png deleted file mode 100644 index d18cb939a9..0000000000 Binary files a/res/flags/TM.png and /dev/null differ diff --git a/res/flags/TN.png b/res/flags/TN.png deleted file mode 100644 index 21c4b98be7..0000000000 Binary files a/res/flags/TN.png and /dev/null differ diff --git a/res/flags/TO.png b/res/flags/TO.png deleted file mode 100644 index c828206e35..0000000000 Binary files a/res/flags/TO.png and /dev/null differ diff --git a/res/flags/TR.png b/res/flags/TR.png deleted file mode 100644 index f2a5bd22c8..0000000000 Binary files a/res/flags/TR.png and /dev/null differ diff --git a/res/flags/TT.png b/res/flags/TT.png deleted file mode 100644 index 66d698334b..0000000000 Binary files a/res/flags/TT.png and /dev/null differ diff --git a/res/flags/TV.png b/res/flags/TV.png deleted file mode 100644 index 7a127f51ae..0000000000 Binary files a/res/flags/TV.png and /dev/null differ diff --git a/res/flags/TW.png b/res/flags/TW.png deleted file mode 100644 index 2353ba1b0a..0000000000 Binary files a/res/flags/TW.png and /dev/null differ diff --git a/res/flags/TZ.png b/res/flags/TZ.png deleted file mode 100644 index 7949f65d8a..0000000000 Binary files a/res/flags/TZ.png and /dev/null differ diff --git a/res/flags/UA.png b/res/flags/UA.png deleted file mode 100644 index 687e305294..0000000000 Binary files a/res/flags/UA.png and /dev/null differ diff --git a/res/flags/UG.png b/res/flags/UG.png deleted file mode 100644 index 0a21ad15c3..0000000000 Binary files a/res/flags/UG.png and /dev/null differ diff --git a/res/flags/US.png b/res/flags/US.png deleted file mode 100644 index c3a245b767..0000000000 Binary files a/res/flags/US.png and /dev/null differ diff --git a/res/flags/UY.png b/res/flags/UY.png deleted file mode 100644 index 21a347c6fc..0000000000 Binary files a/res/flags/UY.png and /dev/null differ diff --git a/res/flags/UZ.png b/res/flags/UZ.png deleted file mode 100644 index 643b6ae0cf..0000000000 Binary files a/res/flags/UZ.png and /dev/null differ diff --git a/res/flags/VA.png b/res/flags/VA.png deleted file mode 100644 index 63a13c0e81..0000000000 Binary files a/res/flags/VA.png and /dev/null differ diff --git a/res/flags/VC.png b/res/flags/VC.png deleted file mode 100644 index da991a9344..0000000000 Binary files a/res/flags/VC.png and /dev/null differ diff --git a/res/flags/VE.png b/res/flags/VE.png deleted file mode 100644 index e75e17c9f0..0000000000 Binary files a/res/flags/VE.png and /dev/null differ diff --git a/res/flags/VG.png b/res/flags/VG.png deleted file mode 100644 index 46f93cad1e..0000000000 Binary files a/res/flags/VG.png and /dev/null differ diff --git a/res/flags/VI.png b/res/flags/VI.png deleted file mode 100644 index 8c849a733e..0000000000 Binary files a/res/flags/VI.png and /dev/null differ diff --git a/res/flags/VN.png b/res/flags/VN.png deleted file mode 100644 index 6ea2122f9d..0000000000 Binary files a/res/flags/VN.png and /dev/null differ diff --git a/res/flags/VU.png b/res/flags/VU.png deleted file mode 100644 index bad3ba4d46..0000000000 Binary files a/res/flags/VU.png and /dev/null differ diff --git a/res/flags/WF.png b/res/flags/WF.png deleted file mode 100644 index d94359dcc4..0000000000 Binary files a/res/flags/WF.png and /dev/null differ diff --git a/res/flags/WS.png b/res/flags/WS.png deleted file mode 100644 index f8b80e5ba9..0000000000 Binary files a/res/flags/WS.png and /dev/null differ diff --git a/res/flags/YE.png b/res/flags/YE.png deleted file mode 100644 index 8b9bbd8942..0000000000 Binary files a/res/flags/YE.png and /dev/null differ diff --git a/res/flags/YT.png b/res/flags/YT.png deleted file mode 100644 index 328879361e..0000000000 Binary files a/res/flags/YT.png and /dev/null differ diff --git a/res/flags/ZA.png b/res/flags/ZA.png deleted file mode 100644 index 7f0a52d3b2..0000000000 Binary files a/res/flags/ZA.png and /dev/null differ diff --git a/res/flags/ZM.png b/res/flags/ZM.png deleted file mode 100644 index 87adc3afaa..0000000000 Binary files a/res/flags/ZM.png and /dev/null differ diff --git a/res/flags/ZW.png b/res/flags/ZW.png deleted file mode 100644 index 742c9f7e71..0000000000 Binary files a/res/flags/ZW.png and /dev/null differ diff --git a/res/media/busy.mp3 b/res/media/busy.mp3 deleted file mode 100644 index fec27ba4c5..0000000000 Binary files a/res/media/busy.mp3 and /dev/null differ diff --git a/res/media/busy.ogg b/res/media/busy.ogg deleted file mode 100644 index 5d64a7d0d9..0000000000 Binary files a/res/media/busy.ogg and /dev/null differ diff --git a/res/media/callend.mp3 b/res/media/callend.mp3 deleted file mode 100644 index 50c34e5640..0000000000 Binary files a/res/media/callend.mp3 and /dev/null differ diff --git a/res/media/callend.ogg b/res/media/callend.ogg deleted file mode 100644 index 927ce1f634..0000000000 Binary files a/res/media/callend.ogg and /dev/null differ diff --git a/res/media/message.mp3 b/res/media/message.mp3 deleted file mode 100644 index b87eeda7c2..0000000000 Binary files a/res/media/message.mp3 and /dev/null differ diff --git a/res/media/message.ogg b/res/media/message.ogg deleted file mode 100644 index adc74437d0..0000000000 Binary files a/res/media/message.ogg and /dev/null differ diff --git a/res/media/ring.mp3 b/res/media/ring.mp3 deleted file mode 100644 index 36200cd89d..0000000000 Binary files a/res/media/ring.mp3 and /dev/null differ diff --git a/res/media/ring.ogg b/res/media/ring.ogg deleted file mode 100644 index 708213bfac..0000000000 Binary files a/res/media/ring.ogg and /dev/null differ diff --git a/res/media/ringback.mp3 b/res/media/ringback.mp3 deleted file mode 100644 index 6ee34bf395..0000000000 Binary files a/res/media/ringback.mp3 and /dev/null differ diff --git a/res/media/ringback.ogg b/res/media/ringback.ogg deleted file mode 100644 index 7dbfdcd017..0000000000 Binary files a/res/media/ringback.ogg and /dev/null differ diff --git a/src/components/structures/BottomLeftMenu.js b/src/components/structures/BottomLeftMenu.js deleted file mode 100644 index 3271d5aeab..0000000000 --- a/src/components/structures/BottomLeftMenu.js +++ /dev/null @@ -1,197 +0,0 @@ -/* -Copyright 2015, 2016 OpenMarket Ltd -Copyright 2017 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 ReactDOM from 'react-dom'; -import sdk from 'matrix-react-sdk'; -import dis from 'matrix-react-sdk/lib/dispatcher'; -import Velocity from 'velocity-vector'; -import 'velocity-vector/velocity.ui'; -import SettingsStore from "matrix-react-sdk/lib/settings/SettingsStore"; - -const CALLOUT_ANIM_DURATION = 1000; - -module.exports = React.createClass({ - displayName: 'BottomLeftMenu', - - propTypes: { - collapsed: React.PropTypes.bool.isRequired, - }, - - getInitialState: function() { - return({ - directoryHover : false, - roomsHover : false, - homeHover: false, - peopleHover : false, - settingsHover : false, - }); - }, - - componentWillMount: function() { - this._dispatcherRef = dis.register(this.onAction); - this._peopleButton = null; - this._directoryButton = null; - this._createRoomButton = null; - this._lastCallouts = {}; - }, - - componentWillUnmount: function() { - dis.unregister(this._dispatcherRef); - }, - - // Room events - onDirectoryClick: function() { - dis.dispatch({ action: 'view_room_directory' }); - }, - - onDirectoryMouseEnter: function() { - this.setState({ directoryHover: true }); - }, - - onDirectoryMouseLeave: function() { - this.setState({ directoryHover: false }); - }, - - onRoomsClick: function() { - dis.dispatch({ action: 'view_create_room' }); - }, - - onRoomsMouseEnter: function() { - this.setState({ roomsHover: true }); - }, - - onRoomsMouseLeave: function() { - this.setState({ roomsHover: false }); - }, - - // Home button events - onHomeClick: function() { - dis.dispatch({ action: 'view_home_page' }); - }, - - onHomeMouseEnter: function() { - this.setState({ homeHover: true }); - }, - - onHomeMouseLeave: function() { - this.setState({ homeHover: false }); - }, - - // People events - onPeopleClick: function() { - dis.dispatch({ action: 'view_create_chat' }); - }, - - onPeopleMouseEnter: function() { - this.setState({ peopleHover: true }); - }, - - onPeopleMouseLeave: function() { - this.setState({ peopleHover: false }); - }, - - // Settings events - onSettingsClick: function() { - dis.dispatch({ action: 'view_user_settings' }); - }, - - onSettingsMouseEnter: function() { - this.setState({ settingsHover: true }); - }, - - onSettingsMouseLeave: function() { - this.setState({ settingsHover: false }); - }, - - onAction: function(payload) { - let calloutElement; - switch (payload.action) { - // Incoming instruction: dance! - case 'callout_start_chat': - calloutElement = this._peopleButton; - break; - case 'callout_room_directory': - calloutElement = this._directoryButton; - break; - case 'callout_create_room': - calloutElement = this._createRoomButton; - break; - } - if (calloutElement) { - const lastCallout = this._lastCallouts[payload.action]; - const now = Date.now(); - if (lastCallout == undefined || lastCallout < now - CALLOUT_ANIM_DURATION) { - this._lastCallouts[payload.action] = now; - Velocity(ReactDOM.findDOMNode(calloutElement), "callout.bounce", CALLOUT_ANIM_DURATION); - } - } - }, - - // Get the label/tooltip to show - getLabel: function(label, show) { - if (show) { - var RoomTooltip = sdk.getComponent("rooms.RoomTooltip"); - return ; - } - }, - - _collectPeopleButton: function(e) { - this._peopleButton = e; - }, - - _collectDirectoryButton: function(e) { - this._directoryButton = e; - }, - - _collectCreateRoomButton: function(e) { - this._createRoomButton = e; - }, - - render: function() { - const HomeButton = sdk.getComponent('elements.HomeButton'); - const StartChatButton = sdk.getComponent('elements.StartChatButton'); - const RoomDirectoryButton = sdk.getComponent('elements.RoomDirectoryButton'); - const CreateRoomButton = sdk.getComponent('elements.CreateRoomButton'); - const SettingsButton = sdk.getComponent('elements.SettingsButton'); - const GroupsButton = sdk.getComponent('elements.GroupsButton'); - - const groupsButton = SettingsStore.getValue("TagPanel.disableTagPanel") ? - : null; - - return ( -
-
- -
- -
-
- -
-
- -
- { groupsButton } - - - -
-
- ); - }, -}); diff --git a/src/components/structures/CompatibilityPage.js b/src/components/structures/CompatibilityPage.js deleted file mode 100644 index 10806f4ffa..0000000000 --- a/src/components/structures/CompatibilityPage.js +++ /dev/null @@ -1,73 +0,0 @@ -/* -Copyright 2015, 2016 OpenMarket 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. -*/ - -'use strict'; - -var React = require('react'); -import { _t } from 'matrix-react-sdk/lib/languageHandler'; - -module.exports = React.createClass({ - displayName: 'CompatibilityPage', - propTypes: { - onAccept: React.PropTypes.func - }, - - getDefaultProps: function() { - return { - onAccept: function() {} // NOP - }; - }, - - onAccept: function() { - this.props.onAccept(); - }, - - render: function() { - - return ( -
-
-

{ _t("Sorry, your browser is not able to run Riot.", {}, { 'b': (sub) => {sub} }) }

-

- { _t("Riot uses many advanced browser features, some of which are not available or experimental in your current browser.") } -

-

- { _t('Please install Chrome or Firefox for the best experience.', - {}, - { - 'chromeLink': (sub) => {sub}, - 'firefoxLink': (sub) => {sub}, - }, - )} - { _t('Safari and Opera work too.', - {}, - { - 'safariLink': (sub) => {sub}, - 'operaLink': (sub) => {sub}, - }, - )} -

-

- { _t("With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!") } -

- -
-
- ); - } -}); diff --git a/src/components/structures/LeftPanel.js b/src/components/structures/LeftPanel.js deleted file mode 100644 index 0fc3e0259b..0000000000 --- a/src/components/structures/LeftPanel.js +++ /dev/null @@ -1,226 +0,0 @@ -/* -Copyright 2015, 2016 OpenMarket 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. -*/ - -'use strict'; - -import React from 'react'; -import PropTypes from 'prop-types'; -import classNames from 'classnames'; -import { MatrixClient } from 'matrix-js-sdk'; -import { KeyCode } from 'matrix-react-sdk/lib/Keyboard'; -import sdk from 'matrix-react-sdk'; -import dis from 'matrix-react-sdk/lib/dispatcher'; -import VectorConferenceHandler from '../../VectorConferenceHandler'; - -import SettingsStore from 'matrix-react-sdk/lib/settings/SettingsStore'; - - -var LeftPanel = React.createClass({ - displayName: 'LeftPanel', - - // NB. If you add props, don't forget to update - // shouldComponentUpdate! - propTypes: { - collapsed: PropTypes.bool.isRequired, - }, - - contextTypes: { - matrixClient: PropTypes.instanceOf(MatrixClient), - }, - - getInitialState: function() { - return { - searchFilter: '', - }; - }, - - componentWillMount: function() { - this.focusedElement = null; - }, - - shouldComponentUpdate: function(nextProps, nextState) { - // MatrixChat will update whenever the user switches - // rooms, but propagating this change all the way down - // the react tree is quite slow, so we cut this off - // here. The RoomTiles listen for the room change - // events themselves to know when to update. - // We just need to update if any of these things change. - if ( - this.props.collapsed !== nextProps.collapsed || - this.props.disabled !== nextProps.disabled - ) { - return true; - } - - if (this.state.searchFilter !== nextState.searchFilter) { - return true; - } - - return false; - }, - - _onFocus: function(ev) { - this.focusedElement = ev.target; - }, - - _onBlur: function(ev) { - this.focusedElement = null; - }, - - _onKeyDown: function(ev) { - if (!this.focusedElement) return; - let handled = false; - - switch (ev.keyCode) { - case KeyCode.UP: - this._onMoveFocus(true); - handled = true; - break; - case KeyCode.DOWN: - this._onMoveFocus(false); - handled = true; - break; - } - - if (handled) { - ev.stopPropagation(); - ev.preventDefault(); - } - }, - - _onMoveFocus: function(up) { - var element = this.focusedElement; - - // unclear why this isn't needed - // var descending = (up == this.focusDirection) ? this.focusDescending : !this.focusDescending; - // this.focusDirection = up; - - var descending = false; // are we currently descending or ascending through the DOM tree? - var classes; - - do { - var child = up ? element.lastElementChild : element.firstElementChild; - var sibling = up ? element.previousElementSibling : element.nextElementSibling; - - if (descending) { - if (child) { - element = child; - } - else if (sibling) { - element = sibling; - } - else { - descending = false; - element = element.parentElement; - } - } - else { - if (sibling) { - element = sibling; - descending = true; - } - else { - element = element.parentElement; - } - } - - if (element) { - classes = element.classList; - if (classes.contains("mx_LeftPanel")) { // we hit the top - element = up ? element.lastElementChild : element.firstElementChild; - descending = true; - } - } - - } while(element && !( - classes.contains("mx_RoomTile") || - classes.contains("mx_SearchBox_search") || - classes.contains("mx_RoomSubList_ellipsis"))); - - if (element) { - element.focus(); - this.focusedElement = element; - this.focusedDescending = descending; - } - }, - - onHideClick: function() { - dis.dispatch({ - action: 'hide_left_panel', - }); - }, - - onSearch: function(term) { - this.setState({ searchFilter: term }); - }, - - collectRoomList: function(ref) { - this._roomList = ref; - }, - - render: function() { - const RoomList = sdk.getComponent('rooms.RoomList'); - const TagPanel = sdk.getComponent('structures.TagPanel'); - const BottomLeftMenu = sdk.getComponent('structures.BottomLeftMenu'); - const CallPreview = sdk.getComponent('voip.CallPreview'); - - let topBox; - if (this.context.matrixClient.isGuest()) { - const LoginBox = sdk.getComponent('structures.LoginBox'); - topBox = ; - } else { - const SearchBox = sdk.getComponent('structures.SearchBox'); - topBox = ; - } - - const classes = classNames( - "mx_LeftPanel", - { - "collapsed": this.props.collapsed, - }, - ); - - const tagPanelEnabled = !SettingsStore.getValue("TagPanel.disableTagPanel"); - const tagPanel = tagPanelEnabled ? :
; - - const containerClasses = classNames( - "mx_LeftPanel_container", "mx_fadable", - { - "mx_LeftPanel_container_collapsed": this.props.collapsed, - "mx_LeftPanel_container_hasTagPanel": tagPanelEnabled, - "mx_fadable_faded": this.props.disabled, - }, - ); - - return ( -
- { tagPanel } - -
- ); - } -}); - -module.exports = LeftPanel; diff --git a/src/components/structures/LoginBox.js b/src/components/structures/LoginBox.js deleted file mode 100644 index 7cacc14e8a..0000000000 --- a/src/components/structures/LoginBox.js +++ /dev/null @@ -1,93 +0,0 @@ -/* -Copyright 2017 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. -*/ - -'use strict'; - -var React = require('react'); -import { _t } from 'matrix-react-sdk/lib/languageHandler'; -var sdk = require('matrix-react-sdk') -var dis = require('matrix-react-sdk/lib/dispatcher'); -var rate_limited_func = require('matrix-react-sdk/lib/ratelimitedfunc'); -var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton'); - -module.exports = React.createClass({ - displayName: 'LoginBox', - - propTypes: { - collapsed: React.PropTypes.bool, - }, - - onToggleCollapse: function(show) { - if (show) { - dis.dispatch({ - action: 'show_left_panel', - }); - } - else { - dis.dispatch({ - action: 'hide_left_panel', - }); - } - }, - - onLoginClick: function() { - dis.dispatch({ action: 'start_login' }); - }, - - onRegisterClick: function() { - dis.dispatch({ action: 'start_registration' }); - }, - - render: function() { - var TintableSvg = sdk.getComponent('elements.TintableSvg'); - - var toggleCollapse; - if (this.props.collapsed) { - toggleCollapse = - - - - } - else { - toggleCollapse = - - - - } - - var loginButton; - if (!this.props.collapsed) { - loginButton = ( -
- - { _t("Login") } - - - { _t("Register") } - -
- ); - } - - var self = this; - return ( -
- { loginButton } - { toggleCollapse } -
- ); - } -}); diff --git a/src/components/structures/RightPanel.js b/src/components/structures/RightPanel.js deleted file mode 100644 index 39463a6700..0000000000 --- a/src/components/structures/RightPanel.js +++ /dev/null @@ -1,424 +0,0 @@ -/* -Copyright 2015, 2016 OpenMarket Ltd -Copyright 2017 Vector Creations Ltd -Copyright 2017 New Vector 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 classNames from 'classnames'; -import { _t } from 'matrix-react-sdk/lib/languageHandler'; -import sdk from 'matrix-react-sdk'; -import dis from 'matrix-react-sdk/lib/dispatcher'; -import { MatrixClient } from 'matrix-js-sdk'; -import Analytics from 'matrix-react-sdk/lib/Analytics'; -import RateLimitedFunc from 'matrix-react-sdk/lib/ratelimitedfunc'; -import AccessibleButton from 'matrix-react-sdk/lib/components/views/elements/AccessibleButton'; -import { showGroupInviteDialog, showGroupAddRoomDialog } from 'matrix-react-sdk/lib/GroupAddressPicker'; -import GroupStoreCache from 'matrix-react-sdk/lib/stores/GroupStoreCache'; - -import { formatCount } from 'matrix-react-sdk/lib/utils/FormattingUtils'; - -class HeaderButton extends React.Component { - constructor() { - super(); - this.onClick = this.onClick.bind(this); - } - - onClick(ev) { - Analytics.trackEvent(...this.props.analytics); - dis.dispatch({ - action: 'view_right_panel_phase', - phase: this.props.clickPhase, - }); - } - - render() { - const TintableSvg = sdk.getComponent("elements.TintableSvg"); - const AccessibleButton = sdk.getComponent("elements.AccessibleButton"); - - return - -
- { this.props.badge ? this.props.badge :   } -
- - { this.props.isHighlighted ?
:
} - - ; - } -} - -HeaderButton.propTypes = { - // Whether this button is highlighted - isHighlighted: PropTypes.bool.isRequired, - // The phase to swap to when the button is clicked - clickPhase: PropTypes.string.isRequired, - // The source file of the icon to display - iconSrc: PropTypes.string.isRequired, - - // The badge to display above the icon - badge: PropTypes.node, - // The parameters to track the click event - analytics: PropTypes.arrayOf(PropTypes.string).isRequired, - - // Button title - title: PropTypes.string.isRequired, -}; - -module.exports = React.createClass({ - displayName: 'RightPanel', - - propTypes: { - // TODO: We're trying to move away from these being props, but we need to know - // whether we should be displaying a room or group member list - roomId: React.PropTypes.string, // if showing panels for a given room, this is set - groupId: React.PropTypes.string, // if showing panels for a given group, this is set - collapsed: React.PropTypes.bool, // currently unused property to request for a minimized view of the panel - }, - - contextTypes: { - matrixClient: PropTypes.instanceOf(MatrixClient), - }, - - Phase: { - RoomMemberList: 'RoomMemberList', - GroupMemberList: 'GroupMemberList', - GroupRoomList: 'GroupRoomList', - GroupRoomInfo: 'GroupRoomInfo', - FilePanel: 'FilePanel', - NotificationPanel: 'NotificationPanel', - RoomMemberInfo: 'RoomMemberInfo', - GroupMemberInfo: 'GroupMemberInfo', - }, - - componentWillMount: function() { - this.dispatcherRef = dis.register(this.onAction); - const cli = this.context.matrixClient; - cli.on("RoomState.members", this.onRoomStateMember); - this._initGroupStore(this.props.groupId); - }, - - componentWillUnmount: function() { - dis.unregister(this.dispatcherRef); - if (this.context.matrixClient) { - this.context.matrixClient.removeListener("RoomState.members", this.onRoomStateMember); - } - this._unregisterGroupStore(); - }, - - getInitialState: function() { - return { - phase: this.props.groupId ? this.Phase.GroupMemberList : this.Phase.RoomMemberList, - isUserPrivilegedInGroup: null, - }; - }, - - componentWillReceiveProps(newProps) { - if (newProps.groupId !== this.props.groupId) { - this._unregisterGroupStore(); - this._initGroupStore(newProps.groupId); - } - }, - - _initGroupStore(groupId) { - if (!groupId) return; - this._groupStore = GroupStoreCache.getGroupStore(groupId); - this._groupStore.registerListener(this.onGroupStoreUpdated); - }, - - _unregisterGroupStore() { - if (this._groupStore) { - this._groupStore.unregisterListener(this.onGroupStoreUpdated); - } - }, - - onGroupStoreUpdated: function() { - this.setState({ - isUserPrivilegedInGroup: this._groupStore.isUserPrivileged(), - }); - }, - - onCollapseClick: function() { - dis.dispatch({ - action: 'hide_right_panel', - }); - }, - - onInviteButtonClick: function() { - if (this.context.matrixClient.isGuest()) { - dis.dispatch({action: 'view_set_mxid'}); - return; - } - - // call AddressPickerDialog - dis.dispatch({ - action: 'view_invite', - roomId: this.props.roomId, - }); - }, - - onInviteToGroupButtonClick: function() { - showGroupInviteDialog(this.props.groupId).then(() => { - this.setState({ - phase: this.Phase.GroupMemberList, - }); - }); - }, - - onAddRoomToGroupButtonClick: function() { - showGroupAddRoomDialog(this.props.groupId).then(() => { - this.forceUpdate(); - }); - }, - - onRoomStateMember: function(ev, state, member) { - // redraw the badge on the membership list - if (this.state.phase === this.Phase.RoomMemberList && member.roomId === this.props.roomId) { - this._delayedUpdate(); - } else if (this.state.phase === this.Phase.RoomMemberInfo && member.roomId === this.props.roomId && - member.userId === this.state.member.userId) { - // refresh the member info (e.g. new power level) - this._delayedUpdate(); - } - }, - - _delayedUpdate: new RateLimitedFunc(function() { - this.forceUpdate(); // eslint-disable-line babel/no-invalid-this - }, 500), - - onAction: function(payload) { - if (payload.action === "view_user") { - dis.dispatch({ - action: 'show_right_panel', - }); - if (payload.member) { - this.setState({ - phase: this.Phase.RoomMemberInfo, - member: payload.member, - }); - } else { - if (this.props.roomId) { - this.setState({ - phase: this.Phase.RoomMemberList, - }); - } else if (this.props.groupId) { - this.setState({ - phase: this.Phase.GroupMemberList, - member: payload.member, - }); - } - } - } else if (payload.action === "view_group") { - this.setState({ - phase: this.Phase.GroupMemberList, - member: null, - }); - } else if (payload.action === "view_group_room") { - this.setState({ - phase: this.Phase.GroupRoomInfo, - groupRoomId: payload.groupRoomId, - }); - } else if (payload.action === "view_group_room_list") { - this.setState({ - phase: this.Phase.GroupRoomList, - }); - } else if (payload.action === "view_group_member_list") { - this.setState({ - phase: this.Phase.GroupMemberList, - }); - } else if (payload.action === "view_group_user") { - this.setState({ - phase: this.Phase.GroupMemberInfo, - member: payload.member, - }); - } else if (payload.action === "view_room") { - this.setState({ - phase: this.Phase.RoomMemberList, - }); - } else if (payload.action === "view_right_panel_phase") { - this.setState({ - phase: payload.phase, - }); - } - }, - - render: function() { - const MemberList = sdk.getComponent('rooms.MemberList'); - const MemberInfo = sdk.getComponent('rooms.MemberInfo'); - const NotificationPanel = sdk.getComponent('structures.NotificationPanel'); - const FilePanel = sdk.getComponent('structures.FilePanel'); - - const GroupMemberList = sdk.getComponent('groups.GroupMemberList'); - const GroupMemberInfo = sdk.getComponent('groups.GroupMemberInfo'); - const GroupRoomList = sdk.getComponent('groups.GroupRoomList'); - const GroupRoomInfo = sdk.getComponent('groups.GroupRoomInfo'); - - const TintableSvg = sdk.getComponent("elements.TintableSvg"); - - let inviteGroup; - - let membersBadge; - let membersTitle = _t('Members'); - if ((this.state.phase === this.Phase.RoomMemberList || this.state.phase === this.Phase.RoomMemberInfo) - && this.props.roomId - ) { - const cli = this.context.matrixClient; - const room = cli.getRoom(this.props.roomId); - let isUserInRoom; - if (room) { - const numMembers = room.getJoinedMembers().length; - membersTitle = _t('%(count)s Members', { count: numMembers }); - membersBadge =
{ formatCount(numMembers) }
; - isUserInRoom = room.hasMembershipState(this.context.matrixClient.credentials.userId, 'join'); - } - - if (isUserInRoom) { - inviteGroup = - -
- -
-
{ _t('Invite to this room') }
-
; - } - } - - const isPhaseGroup = [ - this.Phase.GroupMemberInfo, - this.Phase.GroupMemberList, - ].includes(this.state.phase); - - let headerButtons = []; - if (this.props.roomId) { - headerButtons = [ - , - , - , - ]; - } else if (this.props.groupId) { - headerButtons = [ - , - , - ]; - } - - if (this.props.roomId || this.props.groupId) { - // Hiding the right panel hides it completely and relies on an 'expand' button - // being put in the RoomHeader or GroupView header, so only show the minimise - // button on these 2 screens or you won't be able to re-expand the panel. - headerButtons.push( -
- -
, - ); - } - - let panel =
; - if (!this.props.collapsed) { - if (this.props.roomId && this.state.phase === this.Phase.RoomMemberList) { - panel = ; - } else if (this.props.groupId && this.state.phase === this.Phase.GroupMemberList) { - panel = ; - } else if (this.state.phase === this.Phase.GroupRoomList) { - panel = ; - } else if (this.state.phase === this.Phase.RoomMemberInfo) { - panel = ; - } else if (this.state.phase === this.Phase.GroupMemberInfo) { - panel = ; - } else if (this.state.phase === this.Phase.GroupRoomInfo) { - panel = ; - } else if (this.state.phase === this.Phase.NotificationPanel) { - panel = ; - } else if (this.state.phase === this.Phase.FilePanel) { - panel = ; - } - } - - if (!panel) { - panel =
; - } - - if (this.props.groupId && this.state.isUserPrivilegedInGroup) { - inviteGroup = isPhaseGroup ? ( - -
- -
-
{ _t('Invite to this community') }
-
- ) : ( - -
- -
-
{ _t('Add rooms to this community') }
-
- ); - } - - const classes = classNames("mx_RightPanel", "mx_fadable", { - "collapsed": this.props.collapsed, - "mx_fadable_faded": this.props.disabled, - }); - - return ( - - ); - }, -}); diff --git a/src/components/structures/RoomDirectory.js b/src/components/structures/RoomDirectory.js deleted file mode 100644 index 126ae40401..0000000000 --- a/src/components/structures/RoomDirectory.js +++ /dev/null @@ -1,587 +0,0 @@ -/* -Copyright 2015, 2016 OpenMarket 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. -*/ - -'use strict'; - -var React = require('react'); - -var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg'); -var ContentRepo = require("matrix-js-sdk").ContentRepo; -var Modal = require('matrix-react-sdk/lib/Modal'); -var sdk = require('matrix-react-sdk'); -var dis = require('matrix-react-sdk/lib/dispatcher'); - -var linkify = require('linkifyjs'); -var linkifyString = require('linkifyjs/string'); -var linkifyMatrix = require('matrix-react-sdk/lib/linkify-matrix'); -var sanitizeHtml = require('sanitize-html'); -import Promise from 'bluebird'; - -import { _t } from 'matrix-react-sdk/lib/languageHandler'; - -import {instanceForInstanceId, protocolNameForInstanceId} from '../../utils/DirectoryUtils'; - -linkifyMatrix(linkify); - -module.exports = React.createClass({ - displayName: 'RoomDirectory', - - propTypes: { - config: React.PropTypes.object, - }, - - getDefaultProps: function() { - return { - config: {}, - } - }, - - getInitialState: function() { - return { - publicRooms: [], - loading: true, - protocolsLoading: true, - instanceId: null, - includeAll: false, - roomServer: null, - filterString: null, - } - }, - - componentWillMount: function() { - this._unmounted = false; - this.nextBatch = null; - this.filterTimeout = null; - this.scrollPanel = null; - this.protocols = null; - - this.setState({protocolsLoading: true}); - MatrixClientPeg.get().getThirdpartyProtocols().done((response) => { - this.protocols = response; - this.setState({protocolsLoading: false}); - }, (err) => { - console.warn(`error loading thirdparty protocols: ${err}`); - this.setState({protocolsLoading: false}); - if (MatrixClientPeg.get().isGuest()) { - // Guests currently aren't allowed to use this API, so - // ignore this as otherwise this error is literally the - // thing you see when loading the client! - return; - } - const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createTrackedDialog('Failed to get protocol list from Home Server', '', ErrorDialog, { - title: _t('Failed to get protocol list from Home Server'), - description: _t('The Home Server may be too old to support third party networks'), - }); - }); - - // dis.dispatch({ - // action: 'panel_disable', - // sideDisabled: true, - // middleDisabled: true, - // }); - }, - - componentWillUnmount: function() { - // dis.dispatch({ - // action: 'panel_disable', - // sideDisabled: false, - // middleDisabled: false, - // }); - if (this.filterTimeout) { - clearTimeout(this.filterTimeout); - } - this._unmounted = true; - }, - - refreshRoomList: function() { - this.nextBatch = null; - this.setState({ - publicRooms: [], - loading: true, - }); - this.getMoreRooms().done(); - }, - - getMoreRooms: function() { - if (!MatrixClientPeg.get()) return Promise.resolve(); - - const my_filter_string = this.state.filterString; - const my_server = this.state.roomServer; - // remember the next batch token when we sent the request - // too. If it's changed, appending to the list will corrupt it. - const my_next_batch = this.nextBatch; - const opts = {limit: 20}; - if (my_server != MatrixClientPeg.getHomeServerName()) { - opts.server = my_server; - } - if (this.state.instanceId) { - opts.third_party_instance_id = this.state.instanceId; - } else if (this.state.includeAll) { - opts.include_all_networks = true; - } - if (this.nextBatch) opts.since = this.nextBatch; - if (my_filter_string) opts.filter = { generic_search_term: my_filter_string } ; - return MatrixClientPeg.get().publicRooms(opts).then((data) => { - if ( - my_filter_string != this.state.filterString || - my_server != this.state.roomServer || - my_next_batch != this.nextBatch) - { - // if the filter or server has changed since this request was sent, - // throw away the result (don't even clear the busy flag - // since we must still have a request in flight) - return; - } - - if (this._unmounted) { - // if we've been unmounted, we don't care either. - return; - } - - this.nextBatch = data.next_batch; - this.setState((s) => { - s.publicRooms.push(...data.chunk); - s.loading = false; - return s; - }); - return Boolean(data.next_batch); - }, (err) => { - if ( - my_filter_string != this.state.filterString || - my_server != this.state.roomServer || - my_next_batch != this.nextBatch) - { - // as above: we don't care about errors for old - // requests either - return; - } - - if (this._unmounted) { - // if we've been unmounted, we don't care either. - return; - } - - this.setState({ loading: false }); - console.error("Failed to get publicRooms: %s", JSON.stringify(err)); - var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createTrackedDialog('Failed to get public room list', '', ErrorDialog, { - title: _t('Failed to get public room list'), - description: ((err && err.message) ? err.message : _t('The server may be unavailable or overloaded')) - }); - }); - }, - - /** - * A limited interface for removing rooms from the directory. - * Will set the room to not be publicly visible and delete the - * default alias. In the long term, it would be better to allow - * HS admins to do this through the RoomSettings interface, but - * this needs SPEC-417. - */ - removeFromDirectory: function(room) { - var alias = get_display_alias_for_room(room); - var name = room.name || alias || _t('Unnamed room'); - - var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - - var desc; - if (alias) { - desc = _t('Delete the room alias %(alias)s and remove %(name)s from the directory?', {alias: alias, name: name}); - } else { - desc = _t('Remove %(name)s from the directory?', {name: name}); - } - - Modal.createTrackedDialog('Remove from Directory', '', QuestionDialog, { - title: _t('Remove from Directory'), - description: desc, - onFinished: (should_delete) => { - if (!should_delete) return; - - var Loader = sdk.getComponent("elements.Spinner"); - var modal = Modal.createDialog(Loader); - var step = _t('remove %(name)s from the directory.', {name: name}); - - MatrixClientPeg.get().setRoomDirectoryVisibility(room.room_id, 'private').then(() => { - if (!alias) return; - step = _t('delete the alias.'); - return MatrixClientPeg.get().deleteAlias(alias); - }).done(() => { - modal.close(); - this.refreshRoomList(); - }, (err) => { - modal.close(); - this.refreshRoomList(); - console.error("Failed to " + step + ": " + err); - Modal.createTrackedDialog('Remove from Directory Error', '', ErrorDialog, { - title: _t('Error'), - description: ((err && err.message) ? err.message : _t('The server may be unavailable or overloaded')) - }); - }); - } - }); - }, - - onRoomClicked: function(room, ev) { - if (ev.shiftKey) { - ev.preventDefault(); - this.removeFromDirectory(room); - } else { - this.showRoom(room); - } - }, - - onOptionChange: function(server, instanceId, includeAll) { - // clear next batch so we don't try to load more rooms - this.nextBatch = null; - this.setState({ - // Clear the public rooms out here otherwise we needlessly - // spend time filtering lots of rooms when we're about to - // to clear the list anyway. - publicRooms: [], - roomServer: server, - instanceId: instanceId, - includeAll: includeAll, - }, this.refreshRoomList); - // We also refresh the room list each time even though this - // filtering is client-side. It hopefully won't be client side - // for very long, and we may have fetched a thousand rooms to - // find the five gitter ones, at which point we do not want - // to render all those rooms when switching back to 'all networks'. - // Easiest to just blow away the state & re-fetch. - }, - - onFillRequest: function(backwards) { - if (backwards || !this.nextBatch) return Promise.resolve(false); - - return this.getMoreRooms(); - }, - - onFilterChange: function(alias) { - this.setState({ - filterString: alias || null, - }); - - // don't send the request for a little bit, - // no point hammering the server with a - // request for every keystroke, let the - // user finish typing. - if (this.filterTimeout) { - clearTimeout(this.filterTimeout); - } - this.filterTimeout = setTimeout(() => { - this.filterTimeout = null; - this.refreshRoomList(); - }, 700); - }, - - onFilterClear: function() { - // update immediately - this.setState({ - filterString: null, - }, this.refreshRoomList); - - if (this.filterTimeout) { - clearTimeout(this.filterTimeout); - } - }, - - onJoinClick: function(alias) { - // If we don't have a particular instance id selected, just show that rooms alias - if (!this.state.instanceId) { - // If the user specified an alias without a domain, add on whichever server is selected - // in the dropdown - if (alias.indexOf(':') == -1) { - alias = alias + ':' + this.state.roomServer; - } - this.showRoomAlias(alias); - } else { - // This is a 3rd party protocol. Let's see if we can join it - const protocolName = protocolNameForInstanceId(this.protocols, this.state.instanceId); - const instance = instanceForInstanceId(this.protocols, this.state.instanceId); - const fields = protocolName ? this._getFieldsForThirdPartyLocation(alias, this.protocols[protocolName], instance) : null; - if (!fields) { - const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createTrackedDialog('Unable to join network', '', ErrorDialog, { - title: _t('Unable to join network'), - description: _t('Riot does not know how to join a room on this network'), - }); - return; - } - MatrixClientPeg.get().getThirdpartyLocation(protocolName, fields).done((resp) => { - if (resp.length > 0 && resp[0].alias) { - this.showRoomAlias(resp[0].alias); - } else { - const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createTrackedDialog('Room not found', '', ErrorDialog, { - title: _t('Room not found'), - description: _t('Couldn\'t find a matching Matrix room'), - }); - } - }, (e) => { - const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createTrackedDialog('Fetching third party location failed', '', ErrorDialog, { - title: _t('Fetching third party location failed'), - description: _t('Unable to look up room ID from server'), - }); - }); - } - }, - - showRoomAlias: function(alias) { - this.showRoom(null, alias); - }, - - showRoom: function(room, room_alias) { - var payload = {action: 'view_room'}; - if (room) { - // Don't let the user view a room they won't be able to either - // peek or join: fail earlier so they don't have to click back - // to the directory. - if (MatrixClientPeg.get().isGuest()) { - if (!room.world_readable && !room.guest_can_join) { - dis.dispatch({action: 'view_set_mxid'}); - return; - } - } - - if (!room_alias) { - room_alias = get_display_alias_for_room(room); - } - - payload.oob_data = { - avatarUrl: room.avatar_url, - // XXX: This logic is duplicated from the JS SDK which - // would normally decide what the name is. - name: room.name || room_alias || _t('Unnamed room'), - }; - } - // It's not really possible to join Matrix rooms by ID because the HS has no way to know - // which servers to start querying. However, there's no other way to join rooms in - // this list without aliases at present, so if roomAlias isn't set here we have no - // choice but to supply the ID. - if (room_alias) { - payload.room_alias = room_alias; - } else { - payload.room_id = room.room_id; - } - dis.dispatch(payload); - }, - - getRows: function() { - var BaseAvatar = sdk.getComponent('avatars.BaseAvatar'); - - if (!this.state.publicRooms) return []; - - var rooms = this.state.publicRooms; - var rows = []; - var self = this; - var guestRead, guestJoin, perms; - for (var i = 0; i < rooms.length; i++) { - var name = rooms[i].name || get_display_alias_for_room(rooms[i]) || _t('Unnamed room'); - guestRead = null; - guestJoin = null; - - if (rooms[i].world_readable) { - guestRead = ( -
{ _t('World readable') }
- ); - } - if (rooms[i].guest_can_join) { - guestJoin = ( -
{ _t('Guests can join') }
- ); - } - - perms = null; - if (guestRead || guestJoin) { - perms =
{guestRead}{guestJoin}
; - } - - var topic = rooms[i].topic || ''; - topic = linkifyString(sanitizeHtml(topic)); - - rows.push( - {ev.preventDefault();}} - > - - - - -
{ name }
  - { perms } -
-
{ get_display_alias_for_room(rooms[i]) }
- - - { rooms[i].num_joined_members } - - - ); - } - return rows; - }, - - collectScrollPanel: function(element) { - this.scrollPanel = element; - }, - - _stringLooksLikeId: function(s, field_type) { - let pat = /^#[^\s]+:[^\s]/; - if (field_type && field_type.regexp) { - pat = new RegExp(field_type.regexp); - } - - return pat.test(s); - }, - - _getFieldsForThirdPartyLocation: function(userInput, protocol, instance) { - // make an object with the fields specified by that protocol. We - // require that the values of all but the last field come from the - // instance. The last is the user input. - const requiredFields = protocol.location_fields; - if (!requiredFields) return null; - const fields = {}; - for (let i = 0; i < requiredFields.length - 1; ++i) { - const thisField = requiredFields[i]; - if (instance.fields[thisField] === undefined) return null; - fields[thisField] = instance.fields[thisField]; - } - fields[requiredFields[requiredFields.length - 1]] = userInput; - return fields; - }, - - /** - * called by the parent component when PageUp/Down/etc is pressed. - * - * We pass it down to the scroll panel. - */ - handleScrollKey: function(ev) { - if (this.scrollPanel) { - this.scrollPanel.handleScrollKey(ev); - } - }, - - render: function() { - const SimpleRoomHeader = sdk.getComponent('rooms.SimpleRoomHeader'); - const Loader = sdk.getComponent("elements.Spinner"); - - if (this.state.protocolsLoading) { - return ( -
- - -
- ); - } - - let content; - if (this.state.loading) { - content =
- -
; - } else { - const rows = this.getRows(); - // we still show the scrollpanel, at least for now, because - // otherwise we don't fetch more because we don't get a fill - // request from the scrollpanel because there isn't one - let scrollpanel_content; - if (rows.length == 0) { - scrollpanel_content = { _t('No rooms to show') }; - } else { - scrollpanel_content = - - { this.getRows() } - -
; - } - const ScrollPanel = sdk.getComponent("structures.ScrollPanel"); - content = - { scrollpanel_content } - ; - } - - const protocolName = protocolNameForInstanceId(this.protocols, this.state.instanceId); - let instance_expected_field_type; - if ( - protocolName && - this.protocols && - this.protocols[protocolName] && - this.protocols[protocolName].location_fields.length > 0 && - this.protocols[protocolName].field_types - ) { - const last_field = this.protocols[protocolName].location_fields.slice(-1)[0]; - instance_expected_field_type = this.protocols[protocolName].field_types[last_field]; - } - - - let placeholder = _t('Search for a room'); - if (!this.state.instanceId) { - placeholder = _t('#example') + ':' + this.state.roomServer; - } else if (instance_expected_field_type) { - placeholder = instance_expected_field_type.placeholder; - } - - let showJoinButton = this._stringLooksLikeId(this.state.filterString, instance_expected_field_type); - if (protocolName) { - const instance = instanceForInstanceId(this.protocols, this.state.instanceId); - if (this._getFieldsForThirdPartyLocation(this.state.filterString, this.protocols[protocolName], instance) === null) { - showJoinButton = false; - } - } - - const NetworkDropdown = sdk.getComponent('directory.NetworkDropdown'); - const DirectorySearchBox = sdk.getComponent('elements.DirectorySearchBox'); - return ( -
- -
-
- - -
- {content} -
-
- ); - } -}); - -// Similar to matrix-react-sdk's MatrixTools.getDisplayAliasForRoom -// but works with the objects we get from the public room list -function get_display_alias_for_room(room) { - return room.canonical_alias || (room.aliases ? room.aliases[0] : ""); -} diff --git a/src/components/structures/RoomSubList.js b/src/components/structures/RoomSubList.js deleted file mode 100644 index ed092d94ad..0000000000 --- a/src/components/structures/RoomSubList.js +++ /dev/null @@ -1,401 +0,0 @@ -/* -Copyright 2017 Vector Creations Ltd -Copyright 2015, 2016 OpenMarket 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. -*/ - -'use strict'; - -var React = require('react'); -var ReactDOM = require('react-dom'); -var classNames = require('classnames'); -var sdk = require('matrix-react-sdk'); -import { Droppable } from 'react-beautiful-dnd'; -import { _t } from 'matrix-react-sdk/lib/languageHandler'; -var dis = require('matrix-react-sdk/lib/dispatcher'); -var Unread = require('matrix-react-sdk/lib/Unread'); -var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg'); -var RoomNotifs = require('matrix-react-sdk/lib/RoomNotifs'); -var FormattingUtils = require('matrix-react-sdk/lib/utils/FormattingUtils'); -var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton'); -import Modal from 'matrix-react-sdk/lib/Modal'; -import { KeyCode } from 'matrix-react-sdk/lib/Keyboard'; - - -// turn this on for drop & drag console debugging galore -var debug = false; - -const TRUNCATE_AT = 10; - -var RoomSubList = React.createClass({ - displayName: 'RoomSubList', - - debug: debug, - - propTypes: { - list: React.PropTypes.arrayOf(React.PropTypes.object).isRequired, - label: React.PropTypes.string.isRequired, - tagName: React.PropTypes.string, - editable: React.PropTypes.bool, - - order: React.PropTypes.string.isRequired, - - // passed through to RoomTile and used to highlight room with `!` regardless of notifications count - isInvite: React.PropTypes.bool, - - startAsHidden: React.PropTypes.bool, - showSpinner: React.PropTypes.bool, // true to show a spinner if 0 elements when expanded - collapsed: React.PropTypes.bool.isRequired, // is LeftPanel collapsed? - onHeaderClick: React.PropTypes.func, - alwaysShowHeader: React.PropTypes.bool, - incomingCall: React.PropTypes.object, - onShowMoreRooms: React.PropTypes.func, - searchFilter: React.PropTypes.string, - emptyContent: React.PropTypes.node, // content shown if the list is empty - headerItems: React.PropTypes.node, // content shown in the sublist header - extraTiles: React.PropTypes.arrayOf(React.PropTypes.node), // extra elements added beneath tiles - }, - - getInitialState: function() { - return { - hidden: this.props.startAsHidden || false, - truncateAt: TRUNCATE_AT, - sortedList: [], - }; - }, - - getDefaultProps: function() { - return { - onHeaderClick: function() {}, // NOP - onShowMoreRooms: function() {}, // NOP - extraTiles: [], - isInvite: false, - }; - }, - - componentWillMount: function() { - this.setState({ - sortedList: this.applySearchFilter(this.props.list, this.props.searchFilter), - }); - this.dispatcherRef = dis.register(this.onAction); - }, - - componentWillUnmount: function() { - dis.unregister(this.dispatcherRef); - }, - - componentWillReceiveProps: function(newProps) { - // order the room list appropriately before we re-render - //if (debug) console.log("received new props, list = " + newProps.list); - this.setState({ - sortedList: this.applySearchFilter(newProps.list, newProps.searchFilter), - }); - }, - - applySearchFilter: function(list, filter) { - if (filter === "") return list; - return list.filter((room) => { - return room.name && room.name.toLowerCase().indexOf(filter.toLowerCase()) >= 0 - }); - }, - - // The header is collapsable if it is hidden or not stuck - // The dataset elements are added in the RoomList _initAndPositionStickyHeaders method - isCollapsableOnClick: function() { - var stuck = this.refs.header.dataset.stuck; - if (this.state.hidden || stuck === undefined || stuck === "none") { - return true; - } else { - return false; - } - }, - - onAction: function(payload) { - // XXX: Previously RoomList would forceUpdate whenever on_room_read is dispatched, - // but this is no longer true, so we must do it here (and can apply the small - // optimisation of checking that we care about the room being read). - // - // Ultimately we need to transition to a state pushing flow where something - // explicitly notifies the components concerned that the notif count for a room - // has change (e.g. a Flux store). - if (payload.action === 'on_room_read' && - this.props.list.some((r) => r.roomId === payload.roomId) - ) { - this.forceUpdate(); - } - }, - - onClick: function(ev) { - if (this.isCollapsableOnClick()) { - // The header isCollapsable, so the click is to be interpreted as collapse and truncation logic - var isHidden = !this.state.hidden; - this.setState({ hidden : isHidden }); - - if (isHidden) { - // as good a way as any to reset the truncate state - this.setState({ truncateAt : TRUNCATE_AT }); - } - - this.props.onShowMoreRooms(); - this.props.onHeaderClick(isHidden); - } else { - // The header is stuck, so the click is to be interpreted as a scroll to the header - this.props.onHeaderClick(this.state.hidden, this.refs.header.dataset.originalPosition); - } - }, - - onRoomTileClick(roomId, ev) { - dis.dispatch({ - action: 'view_room', - room_id: roomId, - clear_search: (ev && (ev.keyCode == KeyCode.ENTER || ev.keyCode == KeyCode.SPACE)), - }); - }, - - _shouldShowNotifBadge: function(roomNotifState) { - const showBadgeInStates = [RoomNotifs.ALL_MESSAGES, RoomNotifs.ALL_MESSAGES_LOUD]; - return showBadgeInStates.indexOf(roomNotifState) > -1; - }, - - _shouldShowMentionBadge: function(roomNotifState) { - return roomNotifState != RoomNotifs.MUTE; - }, - - /** - * Total up all the notification counts from the rooms - * - * @param {Number} If supplied will only total notifications for rooms outside the truncation number - * @returns {Array} The array takes the form [total, highlight] where highlight is a bool - */ - roomNotificationCount: function(truncateAt) { - var self = this; - - if (this.props.isInvite) { - return [0, true]; - } - - return this.props.list.reduce(function(result, room, index) { - if (truncateAt === undefined || index >= truncateAt) { - var roomNotifState = RoomNotifs.getRoomNotifsState(room.roomId); - var highlight = room.getUnreadNotificationCount('highlight') > 0; - var notificationCount = room.getUnreadNotificationCount(); - - const notifBadges = notificationCount > 0 && self._shouldShowNotifBadge(roomNotifState); - const mentionBadges = highlight && self._shouldShowMentionBadge(roomNotifState); - const badges = notifBadges || mentionBadges; - - if (badges) { - result[0] += notificationCount; - if (highlight) { - result[1] = true; - } - } - } - return result; - }, [0, false]); - }, - - _updateSubListCount: function() { - // Force an update by setting the state to the current state - // Doing it this way rather than using forceUpdate(), so that the shouldComponentUpdate() - // method is honoured - this.setState(this.state); - }, - - makeRoomTiles: function() { - const DNDRoomTile = sdk.getComponent("rooms.DNDRoomTile"); - const RoomTile = sdk.getComponent("rooms.RoomTile"); - return this.state.sortedList.map((room, index) => { - // XXX: is it evil to pass in this as a prop to RoomTile? Yes. - - // We should only use when editable - const RoomTileComponent = this.props.editable ? DNDRoomTile : RoomTile; - return 0 || this.props.isInvite} - isInvite={this.props.isInvite} - refreshSubList={this._updateSubListCount} - incomingCall={null} - onClick={this.onRoomTileClick} - />; - }); - }, - - _getHeaderJsx: function() { - var TintableSvg = sdk.getComponent("elements.TintableSvg"); - - var subListNotifications = this.roomNotificationCount(); - var subListNotifCount = subListNotifications[0]; - var subListNotifHighlight = subListNotifications[1]; - - var totalTiles = this.props.list.length + (this.props.extraTiles || []).length; - var roomCount = totalTiles > 0 ? totalTiles : ''; - - var chevronClasses = classNames({ - 'mx_RoomSubList_chevron': true, - 'mx_RoomSubList_chevronRight': this.state.hidden, - 'mx_RoomSubList_chevronDown': !this.state.hidden, - }); - - var badgeClasses = classNames({ - 'mx_RoomSubList_badge': true, - 'mx_RoomSubList_badgeHighlight': subListNotifHighlight, - }); - - var badge; - if (subListNotifCount > 0) { - badge =
{ FormattingUtils.formatCount(subListNotifCount) }
; - } else if (this.props.isInvite) { - // no notifications but highlight anyway because this is an invite badge - badge =
!
; - } - - // When collapsed, allow a long hover on the header to show user - // the full tag name and room count - var title; - if (this.props.collapsed) { - title = this.props.label; - if (roomCount !== '') { - title += " [" + roomCount + "]"; - } - } - - var incomingCall; - if (this.props.incomingCall) { - var self = this; - // Check if the incoming call is for this section - var incomingCallRoom = this.props.list.filter(function(room) { - return self.props.incomingCall.roomId === room.roomId; - }); - - if (incomingCallRoom.length === 1) { - var IncomingCallBox = sdk.getComponent("voip.IncomingCallBox"); - incomingCall = ; - } - } - - var tabindex = this.props.searchFilter === "" ? "0" : "-1"; - - return ( -
- - { this.props.collapsed ? '' : this.props.label } -
{ roomCount }
-
- { badge } - { incomingCall } -
-
- ); - }, - - _createOverflowTile: function(overflowCount, totalCount) { - var content =
; - - var overflowNotifications = this.roomNotificationCount(TRUNCATE_AT); - var overflowNotifCount = overflowNotifications[0]; - var overflowNotifHighlight = overflowNotifications[1]; - if (overflowNotifCount && !this.props.collapsed) { - content = FormattingUtils.formatCount(overflowNotifCount); - } - - var badgeClasses = classNames({ - 'mx_RoomSubList_moreBadge': true, - 'mx_RoomSubList_moreBadgeNotify': overflowNotifCount && !this.props.collapsed, - 'mx_RoomSubList_moreBadgeHighlight': overflowNotifHighlight && !this.props.collapsed, - }); - - return ( - -
-
{ _t("more") }
-
{ content }
-
- ); - }, - - _showFullMemberList: function() { - this.setState({ - truncateAt: -1 - }); - - this.props.onShowMoreRooms(); - this.props.onHeaderClick(false); - }, - - render: function() { - var connectDropTarget = this.props.connectDropTarget; - var TruncatedList = sdk.getComponent('elements.TruncatedList'); - - var label = this.props.collapsed ? null : this.props.label; - - let content; - if (this.state.sortedList.length === 0 && !this.props.searchFilter && this.props.extraTiles.length === 0) { - content = this.props.emptyContent; - } else { - content = this.makeRoomTiles(); - content.push(...this.props.extraTiles); - } - - if (this.state.sortedList.length > 0 || this.props.extraTiles.length > 0 || this.props.editable) { - var subList; - var classes = "mx_RoomSubList"; - - if (!this.state.hidden) { - subList = - { content } - ; - } - else { - subList = - ; - } - - const subListContent =
- { this._getHeaderJsx() } - { subList } -
; - - return this.props.editable ? - - { (provided, snapshot) => ( -
- { subListContent } -
- ) } -
: subListContent; - } - else { - var Loader = sdk.getComponent("elements.Spinner"); - return ( -
- { this.props.alwaysShowHeader ? this._getHeaderJsx() : undefined } - { (this.props.showSpinner && !this.state.hidden) ? : undefined } -
- ); - } - } -}); - -module.exports = RoomSubList; diff --git a/src/components/structures/SearchBox.js b/src/components/structures/SearchBox.js deleted file mode 100644 index 2d6e6ae04c..0000000000 --- a/src/components/structures/SearchBox.js +++ /dev/null @@ -1,163 +0,0 @@ -/* -Copyright 2015, 2016 OpenMarket 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. -*/ - -'use strict'; - -import React from 'react'; -import { _t } from 'matrix-react-sdk/lib/languageHandler'; -import { KeyCode } from 'matrix-react-sdk/lib/Keyboard'; -import sdk from 'matrix-react-sdk'; -import dis from 'matrix-react-sdk/lib/dispatcher'; -import rate_limited_func from 'matrix-react-sdk/lib/ratelimitedfunc'; -import AccessibleButton from 'matrix-react-sdk/lib/components/views/elements/AccessibleButton'; - -module.exports = React.createClass({ - displayName: 'SearchBox', - - propTypes: { - collapsed: React.PropTypes.bool, - onSearch: React.PropTypes.func, - }, - - getInitialState: function() { - return { - searchTerm: "", - }; - }, - - componentDidMount: function() { - this.dispatcherRef = dis.register(this.onAction); - }, - - componentWillUnmount: function() { - dis.unregister(this.dispatcherRef); - }, - - onAction: function(payload) { - switch (payload.action) { - case 'view_room': - if (this.refs.search && payload.clear_search) { - this._clearSearch(); - } - break; - case 'focus_room_filter': - if (this.refs.search) { - this.refs.search.focus(); - this.refs.search.select(); - } - break; - } - }, - - onChange: function() { - if (!this.refs.search) return; - this.setState({ searchTerm: this.refs.search.value }); - this.onSearch(); - }, - - onSearch: new rate_limited_func( - function() { - this.props.onSearch(this.refs.search.value); - }, - 100 - ), - - onToggleCollapse: function(show) { - if (show) { - dis.dispatch({ - action: 'show_left_panel', - }); - } - else { - dis.dispatch({ - action: 'hide_left_panel', - }); - } - }, - - _onKeyDown: function(ev) { - switch (ev.keyCode) { - case KeyCode.ESCAPE: - this._clearSearch(); - dis.dispatch({action: 'focus_composer'}); - break; - } - }, - - _clearSearch: function() { - this.refs.search.value = ""; - this.onChange(); - }, - - render: function() { - var TintableSvg = sdk.getComponent('elements.TintableSvg'); - - var collapseTabIndex = this.refs.search && this.refs.search.value !== "" ? "-1" : "0"; - - var toggleCollapse; - if (this.props.collapsed) { - toggleCollapse = - - - - } - else { - toggleCollapse = - - - - } - - var searchControls; - if (!this.props.collapsed) { - searchControls = [ - this.state.searchTerm.length > 0 ? - { this._clearSearch(); } }> - - - : - , - - ]; - } - - var self = this; - return ( -
- { searchControls } - { toggleCollapse } -
- ); - } -}); diff --git a/src/components/structures/HomePage.js b/src/components/structures/VectorHomePage.js similarity index 100% rename from src/components/structures/HomePage.js rename to src/components/structures/VectorHomePage.js diff --git a/src/components/structures/ViewSource.js b/src/components/structures/ViewSource.js deleted file mode 100644 index 3a5d35a561..0000000000 --- a/src/components/structures/ViewSource.js +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright 2015, 2016 OpenMarket 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. -*/ - -'use strict'; - -import React from 'react'; -import PropTypes from 'prop-types'; -import SyntaxHighlight from '../views/elements/SyntaxHighlight'; - - -module.exports = React.createClass({ - displayName: 'ViewSource', - - propTypes: { - content: PropTypes.object.isRequired, - onFinished: PropTypes.func.isRequired, - }, - - componentDidMount: function() { - document.addEventListener("keydown", this.onKeyDown); - }, - - componentWillUnmount: function() { - document.removeEventListener("keydown", this.onKeyDown); - }, - - onKeyDown: function(ev) { - if (ev.keyCode == 27) { // escape - ev.stopPropagation(); - ev.preventDefault(); - this.props.onFinished(); - } - }, - - render: function() { - return ( -
- - { JSON.stringify(this.props.content, null, 2) } - -
- ); - } -}); diff --git a/src/components/views/context_menus/GenericElementContextMenu.js b/src/components/views/context_menus/GenericElementContextMenu.js deleted file mode 100644 index 3f4804dbd1..0000000000 --- a/src/components/views/context_menus/GenericElementContextMenu.js +++ /dev/null @@ -1,60 +0,0 @@ -/* -Copyright 2017 New Vector 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. -*/ - -'use strict'; - -import React from 'react'; -import PropTypes from 'prop-types'; - -/* - * This component can be used to display generic HTML content in a contextual - * menu. - */ - - -export default class GenericElementContextMenu extends React.Component { - static PropTypes = { - element: PropTypes.element.isRequired, - // Function to be called when the parent window is resized - // This can be used to reposition or close the menu on resize and - // ensure that it is not displayed in a stale position. - onResize: PropTypes.func, - }; - - constructor(props) { - super(props); - this.resize = this.resize.bind(this); - } - - componentDidMount() { - this.resize = this.resize.bind(this); - window.addEventListener("resize", this.resize); - } - - componentWillUnmount() { - window.removeEventListener("resize", this.resize); - } - - resize() { - if (this.props.onResize) { - this.props.onResize(); - } - } - - render() { - return
{ this.props.element }
; - } -} diff --git a/src/components/views/context_menus/GenericTextContextMenu.js b/src/components/views/context_menus/GenericTextContextMenu.js deleted file mode 100644 index 2319fe05a2..0000000000 --- a/src/components/views/context_menus/GenericTextContextMenu.js +++ /dev/null @@ -1,30 +0,0 @@ -/* -Copyright 2017 Michael Telatynski <7t3chguy@gmail.com> - -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. -*/ - -'use strict'; - -import React from 'react'; -import PropTypes from 'prop-types'; - -export default class GenericTextContextMenu extends React.Component { - static PropTypes = { - message: PropTypes.string.isRequired, - }; - - render() { - return
{ this.props.message }
; - } -} diff --git a/src/components/views/context_menus/MessageContextMenu.js b/src/components/views/context_menus/MessageContextMenu.js deleted file mode 100644 index 11f14f367e..0000000000 --- a/src/components/views/context_menus/MessageContextMenu.js +++ /dev/null @@ -1,326 +0,0 @@ -/* -Copyright 2015, 2016 OpenMarket Ltd -Copyright 2018 New Vector 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. -*/ - -'use strict'; - -import React from 'react'; - -import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg'; -import dis from 'matrix-react-sdk/lib/dispatcher'; -import sdk from 'matrix-react-sdk'; -import { _t } from 'matrix-react-sdk/lib/languageHandler'; -import Modal from 'matrix-react-sdk/lib/Modal'; -import Resend from "matrix-react-sdk/lib/Resend"; -import SettingsStore from "matrix-react-sdk/lib/settings/SettingsStore"; -import {makeEventPermalink} from 'matrix-react-sdk/lib/matrix-to'; -import { isUrlPermitted } from 'matrix-react-sdk/lib/HtmlUtils'; - -module.exports = React.createClass({ - displayName: 'MessageContextMenu', - - propTypes: { - /* the MatrixEvent associated with the context menu */ - mxEvent: React.PropTypes.object.isRequired, - - /* an optional EventTileOps implementation that can be used to unhide preview widgets */ - eventTileOps: React.PropTypes.object, - - /* callback called when the menu is dismissed */ - onFinished: React.PropTypes.func, - }, - - getInitialState: function() { - return { - canRedact: false, - canPin: false, - }; - }, - - componentWillMount: function() { - MatrixClientPeg.get().on('RoomMember.powerLevel', this._checkPermissions); - this._checkPermissions(); - }, - - componentWillUnmount: function() { - const cli = MatrixClientPeg.get(); - if (cli) { - cli.removeListener('RoomMember.powerLevel', this._checkPermissions); - } - }, - - _checkPermissions: function() { - const cli = MatrixClientPeg.get(); - const room = cli.getRoom(this.props.mxEvent.getRoomId()); - - const canRedact = room.currentState.maySendRedactionForEvent(this.props.mxEvent, cli.credentials.userId); - let canPin = room.currentState.mayClientSendStateEvent('m.room.pinned_events', cli); - - // HACK: Intentionally say we can't pin if the user doesn't want to use the functionality - if (!SettingsStore.isFeatureEnabled("feature_pinning")) canPin = false; - - this.setState({canRedact, canPin}); - }, - - _isPinned: function() { - const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId()); - const pinnedEvent = room.currentState.getStateEvents('m.room.pinned_events', ''); - if (!pinnedEvent) return false; - return pinnedEvent.getContent().pinned.includes(this.props.mxEvent.getId()); - }, - - onResendClick: function() { - Resend.resend(this.props.mxEvent); - this.closeMenu(); - }, - - onViewSourceClick: function() { - const ViewSource = sdk.getComponent('structures.ViewSource'); - Modal.createTrackedDialog('View Event Source', '', ViewSource, { - content: this.props.mxEvent.event, - }, 'mx_Dialog_viewsource'); - this.closeMenu(); - }, - - onViewClearSourceClick: function() { - const ViewSource = sdk.getComponent('structures.ViewSource'); - Modal.createTrackedDialog('View Clear Event Source', '', ViewSource, { - // FIXME: _clearEvent is private - content: this.props.mxEvent._clearEvent, - }, 'mx_Dialog_viewsource'); - this.closeMenu(); - }, - - onRedactClick: function() { - const ConfirmRedactDialog = sdk.getComponent("dialogs.ConfirmRedactDialog"); - Modal.createTrackedDialog('Confirm Redact Dialog', '', ConfirmRedactDialog, { - onFinished: (proceed) => { - if (!proceed) return; - - const cli = MatrixClientPeg.get(); - cli.redactEvent(this.props.mxEvent.getRoomId(), this.props.mxEvent.getId()).catch(function(e) { - const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - // display error message stating you couldn't delete this. - const code = e.errcode || e.statusCode; - Modal.createTrackedDialog('You cannot delete this message', '', ErrorDialog, { - title: _t('Error'), - description: _t('You cannot delete this message. (%(code)s)', {code}), - }); - }).done(); - }, - }, 'mx_Dialog_confirmredact'); - this.closeMenu(); - }, - - onCancelSendClick: function() { - Resend.removeFromQueue(this.props.mxEvent); - this.closeMenu(); - }, - - onForwardClick: function() { - dis.dispatch({ - action: 'forward_event', - event: this.props.mxEvent, - }); - this.closeMenu(); - }, - - onPinClick: function() { - MatrixClientPeg.get().getStateEvent(this.props.mxEvent.getRoomId(), 'm.room.pinned_events', '') - .catch((e) => { - // Intercept the Event Not Found error and fall through the promise chain with no event. - if (e.errcode === "M_NOT_FOUND") return null; - throw e; - }) - .then((event) => { - const eventIds = (event ? event.pinned : []) || []; - if (!eventIds.includes(this.props.mxEvent.getId())) { - // Not pinned - add - eventIds.push(this.props.mxEvent.getId()); - } else { - // Pinned - remove - eventIds.splice(eventIds.indexOf(this.props.mxEvent.getId()), 1); - } - - const cli = MatrixClientPeg.get(); - cli.sendStateEvent(this.props.mxEvent.getRoomId(), 'm.room.pinned_events', {pinned: eventIds}, ''); - }); - this.closeMenu(); - }, - - closeMenu: function() { - if (this.props.onFinished) this.props.onFinished(); - }, - - onUnhidePreviewClick: function() { - if (this.props.eventTileOps) { - this.props.eventTileOps.unhideWidget(); - } - this.closeMenu(); - }, - - onQuoteClick: function() { - dis.dispatch({ - action: 'quote', - text: this.props.eventTileOps.getInnerText(), - }); - this.closeMenu(); - }, - - onReplyClick: function() { - dis.dispatch({ - action: 'quote_event', - event: this.props.mxEvent, - }); - this.closeMenu(); - }, - - render: function() { - const eventStatus = this.props.mxEvent.status; - let resendButton; - let redactButton; - let cancelButton; - let forwardButton; - let pinButton; - let viewClearSourceButton; - let unhidePreviewButton; - let externalURLButton; - let quoteButton; - let replyButton; - - if (eventStatus === 'not_sent') { - resendButton = ( -
- { _t('Resend') } -
- ); - } - - if (!eventStatus && this.state.canRedact) { - redactButton = ( -
- { _t('Remove') } -
- ); - } - - if (eventStatus === "queued" || eventStatus === "not_sent") { - cancelButton = ( -
- { _t('Cancel Sending') } -
- ); - } - - if (!eventStatus && this.props.mxEvent.getType() === 'm.room.message') { - const content = this.props.mxEvent.getContent(); - if (content.msgtype && content.msgtype !== 'm.bad.encrypted' && content.hasOwnProperty('body')) { - forwardButton = ( -
- { _t('Forward Message') } -
- ); - - if (SettingsStore.isFeatureEnabled("feature_rich_quoting")) { - replyButton = ( -
- { _t('Reply') } -
- ); - } - - if (this.state.canPin) { - pinButton = ( -
- { this._isPinned() ? _t('Unpin Message') : _t('Pin Message') } -
- ); - } - } - } - - const viewSourceButton = ( -
- { _t('View Source') } -
- ); - - if (this.props.mxEvent.getType() !== this.props.mxEvent.getWireType()) { - viewClearSourceButton = ( -
- { _t('View Decrypted Source') } -
- ); - } - - if (this.props.eventTileOps) { - if (this.props.eventTileOps.isWidgetHidden()) { - unhidePreviewButton = ( -
- { _t('Unhide Preview') } -
- ); - } - } - - // XXX: if we use room ID, we should also include a server where the event can be found (other than in the domain of the event ID) - const permalinkButton = ( - - ); - - if (this.props.eventTileOps && this.props.eventTileOps.getInnerText) { - quoteButton = ( -
- { _t('Quote') } -
- ); - } - - // Bridges can provide a 'external_url' to link back to the source. - if ( - typeof(this.props.mxEvent.event.content.external_url) === "string" && - isUrlPermitted(this.props.mxEvent.event.content.external_url) - ) { - externalURLButton = ( - - ); - } - - - return ( -
- { resendButton } - { redactButton } - { cancelButton } - { forwardButton } - { pinButton } - { viewSourceButton } - { viewClearSourceButton } - { unhidePreviewButton } - { permalinkButton } - { quoteButton } - { replyButton } - { externalURLButton } -
- ); - }, -}); diff --git a/src/components/views/context_menus/PresenceContextMenu.js b/src/components/views/context_menus/PresenceContextMenu.js deleted file mode 100644 index 3a3dc2fa47..0000000000 --- a/src/components/views/context_menus/PresenceContextMenu.js +++ /dev/null @@ -1,101 +0,0 @@ -/* -Copyright 2017 Travis Ralston - -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 { _t, _td } from 'matrix-react-sdk/lib/languageHandler'; -import sdk from 'matrix-react-sdk'; - -const STATUS_LABELS = { - "online": _td("Online"), - "unavailable": _td("Away"), - "offline": _td("Appear Offline"), -}; - -const PresenceContextMenuOption = React.createClass({ - displayName: 'PresenceContextMenuOption', - - propTypes: { - forStatus: React.PropTypes.string.isRequired, - isCurrent: React.PropTypes.bool, - onChange: React.PropTypes.func.isRequired, - }, - - onClick: function() { - if (this.isCurrent) return; - this.props.onChange(this.props.forStatus); - }, - - render: function() { - const AccessibleButton = sdk.getComponent("elements.AccessibleButton"); - - const indicatorClasses = "mx_PresenceContextMenuOption_indicator " - + "mx_PresenceContextMenuOption_indicator_" + this.props.forStatus; - - let classNames = "mx_PresenceContextMenuOption"; - if (this.props.isCurrent) classNames += " mx_PresenceContextMenuOption_current"; - - return ( - -
- { _t(STATUS_LABELS[this.props.forStatus]) } -
- ); - }, -}); - -module.exports = React.createClass({ - displayName: 'PresenceContextMenu', - - propTypes: { - // "online", "unavailable", or "offline" - currentStatus: React.PropTypes.string.isRequired, - - // Called when the user wants to change their status. - // Args: (newStatus:string) - onChange: React.PropTypes.func.isRequired, - - // callback called when the menu is dismissed - onFinished: React.PropTypes.func, - }, - - getInitialState() { - return { - currentStatus: this.props.currentStatus, - }; - }, - - onChange: function(newStatus) { - this.props.onChange(newStatus); - this.setState({currentStatus: newStatus}); - }, - - render: function() { - const statusElements = []; - for (let status of Object.keys(STATUS_LABELS)) { - statusElements.push(( - - )); - } - - return ( -
- { statusElements } -
- ); - }, -}); diff --git a/src/components/views/context_menus/RoomTileContextMenu.js b/src/components/views/context_menus/RoomTileContextMenu.js deleted file mode 100644 index 06eb347d6c..0000000000 --- a/src/components/views/context_menus/RoomTileContextMenu.js +++ /dev/null @@ -1,368 +0,0 @@ -/* -Copyright 2015, 2016 OpenMarket Ltd -Copyright 2017 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. -*/ - -'use strict'; - -import Promise from 'bluebird'; -import React from 'react'; -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import sdk from 'matrix-react-sdk'; -import { _t, _td } from 'matrix-react-sdk/lib/languageHandler'; -import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg'; -import dis from 'matrix-react-sdk/lib/dispatcher'; -import DMRoomMap from 'matrix-react-sdk/lib/utils/DMRoomMap'; -import * as Rooms from 'matrix-react-sdk/lib/Rooms'; -import * as RoomNotifs from 'matrix-react-sdk/lib/RoomNotifs'; -import Modal from 'matrix-react-sdk/lib/Modal'; -import RoomListActions from 'matrix-react-sdk/lib/actions/RoomListActions'; - -module.exports = React.createClass({ - displayName: 'RoomTileContextMenu', - - propTypes: { - room: PropTypes.object.isRequired, - /* callback called when the menu is dismissed */ - onFinished: PropTypes.func, - }, - - getInitialState() { - const dmRoomMap = new DMRoomMap(MatrixClientPeg.get()); - return { - roomNotifState: RoomNotifs.getRoomNotifsState(this.props.room.roomId), - isFavourite: this.props.room.tags.hasOwnProperty("m.favourite"), - isLowPriority: this.props.room.tags.hasOwnProperty("m.lowpriority"), - isDirectMessage: Boolean(dmRoomMap.getUserIdForRoomId(this.props.room.roomId)), - }; - }, - - componentWillMount: function() { - this._unmounted = false; - }, - - componentWillUnmount: function() { - this._unmounted = true; - }, - - _toggleTag: function(tagNameOn, tagNameOff) { - if (!MatrixClientPeg.get().isGuest()) { - Promise.delay(500).then(() => { - dis.dispatch(RoomListActions.tagRoom( - MatrixClientPeg.get(), - this.props.room, - tagNameOff, tagNameOn, - undefined, 0, - ), true); - - this.props.onFinished(); - }); - } - }, - - _onClickFavourite: function() { - // Tag room as 'Favourite' - if (!this.state.isFavourite && this.state.isLowPriority) { - this.setState({ - isFavourite: true, - isLowPriority: false, - }); - this._toggleTag("m.favourite", "m.lowpriority"); - } else if (this.state.isFavourite) { - this.setState({isFavourite: false}); - this._toggleTag(null, "m.favourite"); - } else if (!this.state.isFavourite) { - this.setState({isFavourite: true}); - this._toggleTag("m.favourite"); - } - }, - - _onClickLowPriority: function() { - // Tag room as 'Low Priority' - if (!this.state.isLowPriority && this.state.isFavourite) { - this.setState({ - isFavourite: false, - isLowPriority: true, - }); - this._toggleTag("m.lowpriority", "m.favourite"); - } else if (this.state.isLowPriority) { - this.setState({isLowPriority: false}); - this._toggleTag(null, "m.lowpriority"); - } else if (!this.state.isLowPriority) { - this.setState({isLowPriority: true}); - this._toggleTag("m.lowpriority"); - } - }, - - _onClickDM: function() { - if (MatrixClientPeg.get().isGuest()) return; - - const newIsDirectMessage = !this.state.isDirectMessage; - this.setState({ - isDirectMessage: newIsDirectMessage, - }); - - Rooms.guessAndSetDMRoom( - this.props.room, newIsDirectMessage, - ).delay(500).finally(() => { - // Close the context menu - if (this.props.onFinished) { - this.props.onFinished(); - } - }, (err) => { - const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createTrackedDialog('Failed to set Direct Message status of room', '', ErrorDialog, { - title: _t('Failed to set Direct Message status of room'), - description: ((err && err.message) ? err.message : _t('Operation failed')), - }); - }); - }, - - _onClickLeave: function() { - // Leave room - dis.dispatch({ - action: 'leave_room', - room_id: this.props.room.roomId, - }); - - // Close the context menu - if (this.props.onFinished) { - this.props.onFinished(); - } - }, - - _onClickReject: function() { - dis.dispatch({ - action: 'reject_invite', - room_id: this.props.room.roomId, - }); - - // Close the context menu - if (this.props.onFinished) { - this.props.onFinished(); - } - }, - - _onClickForget: function() { - // FIXME: duplicated with RoomSettings (and dead code in RoomView) - MatrixClientPeg.get().forget(this.props.room.roomId).done(function() { - dis.dispatch({ action: 'view_next_room' }); - }, function(err) { - const errCode = err.errcode || _td("unknown error code"); - const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createTrackedDialog('Failed to forget room', '', ErrorDialog, { - title: _t('Failed to forget room %(errCode)s', {errCode: errCode}), - description: ((err && err.message) ? err.message : _t('Operation failed')), - }); - }); - - // Close the context menu - if (this.props.onFinished) { - this.props.onFinished(); - } - }, - - _saveNotifState: function(newState) { - if (MatrixClientPeg.get().isGuest()) return; - - const oldState = this.state.roomNotifState; - const roomId = this.props.room.roomId; - - this.setState({ - roomNotifState: newState, - }); - RoomNotifs.setRoomNotifsState(roomId, newState).done(() => { - // delay slightly so that the user can see their state change - // before closing the menu - return Promise.delay(500).then(() => { - if (this._unmounted) return; - // Close the context menu - if (this.props.onFinished) { - this.props.onFinished(); - } - }); - }, (error) => { - // TODO: some form of error notification to the user - // to inform them that their state change failed. - // For now we at least set the state back - if (this._unmounted) return; - this.setState({ - roomNotifState: oldState, - }); - }); - }, - - _onClickAlertMe: function() { - this._saveNotifState(RoomNotifs.ALL_MESSAGES_LOUD); - }, - - _onClickAllNotifs: function() { - this._saveNotifState(RoomNotifs.ALL_MESSAGES); - }, - - _onClickMentions: function() { - this._saveNotifState(RoomNotifs.MENTIONS_ONLY); - }, - - _onClickMute: function() { - this._saveNotifState(RoomNotifs.MUTE); - }, - - _renderNotifMenu: function() { - const alertMeClasses = classNames({ - 'mx_RoomTileContextMenu_notif_field': true, - 'mx_RoomTileContextMenu_notif_fieldSet': this.state.roomNotifState == RoomNotifs.ALL_MESSAGES_LOUD, - }); - - const allNotifsClasses = classNames({ - 'mx_RoomTileContextMenu_notif_field': true, - 'mx_RoomTileContextMenu_notif_fieldSet': this.state.roomNotifState == RoomNotifs.ALL_MESSAGES, - }); - - const mentionsClasses = classNames({ - 'mx_RoomTileContextMenu_notif_field': true, - 'mx_RoomTileContextMenu_notif_fieldSet': this.state.roomNotifState == RoomNotifs.MENTIONS_ONLY, - }); - - const muteNotifsClasses = classNames({ - 'mx_RoomTileContextMenu_notif_field': true, - 'mx_RoomTileContextMenu_notif_fieldSet': this.state.roomNotifState == RoomNotifs.MUTE, - }); - - return ( -
-
- -
-
- - - { _t('All messages (noisy)') } -
-
- - - { _t('All messages') } -
-
- - - { _t('Mentions only') } -
-
- - - { _t('Mute') } -
-
- ); - }, - - _renderLeaveMenu: function(membership) { - if (!membership) { - return null; - } - - let leaveClickHandler = null; - let leaveText = null; - - switch (membership) { - case "join": - leaveClickHandler = this._onClickLeave; - leaveText = _t('Leave'); - break; - case "leave": - case "ban": - leaveClickHandler = this._onClickForget; - leaveText = _t('Forget'); - break; - case "invite": - leaveClickHandler = this._onClickReject; - leaveText = _t('Reject'); - break; - } - - return ( -
-
- - { leaveText } -
-
- ); - }, - - _renderRoomTagMenu: function() { - const favouriteClasses = classNames({ - 'mx_RoomTileContextMenu_tag_field': true, - 'mx_RoomTileContextMenu_tag_fieldSet': this.state.isFavourite, - 'mx_RoomTileContextMenu_tag_fieldDisabled': false, - }); - - const lowPriorityClasses = classNames({ - 'mx_RoomTileContextMenu_tag_field': true, - 'mx_RoomTileContextMenu_tag_fieldSet': this.state.isLowPriority, - 'mx_RoomTileContextMenu_tag_fieldDisabled': false, - }); - - const dmClasses = classNames({ - 'mx_RoomTileContextMenu_tag_field': true, - 'mx_RoomTileContextMenu_tag_fieldSet': this.state.isDirectMessage, - 'mx_RoomTileContextMenu_tag_fieldDisabled': false, - }); - - return ( -
-
- - - { _t('Favourite') } -
-
- - - { _t('Low Priority') } -
-
- - - { _t('Direct Chat') } -
-
- ); - }, - - render: function() { - const myMember = this.props.room.getMember( - MatrixClientPeg.get().credentials.userId, - ); - - // Can't set notif level or tags on non-join rooms - if (myMember.membership !== 'join') { - return this._renderLeaveMenu(myMember.membership); - } - - return ( -
- { this._renderNotifMenu() } -
- { this._renderLeaveMenu(myMember.membership) } -
- { this._renderRoomTagMenu() } -
- ); - }, -}); diff --git a/src/components/views/context_menus/TagTileContextMenu.js b/src/components/views/context_menus/TagTileContextMenu.js deleted file mode 100644 index 576e8485a8..0000000000 --- a/src/components/views/context_menus/TagTileContextMenu.js +++ /dev/null @@ -1,75 +0,0 @@ -/* -Copyright 2018 New Vector 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 { _t } from 'matrix-react-sdk/lib/languageHandler'; -import dis from 'matrix-react-sdk/lib/dispatcher'; -import TagOrderActions from 'matrix-react-sdk/lib/actions/TagOrderActions'; -import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg'; -import sdk from 'matrix-react-sdk/lib/index'; - -export default class TagTileContextMenu extends React.Component { - static propTypes = { - tag: PropTypes.string.isRequired, - /* callback called when the menu is dismissed */ - onFinished: PropTypes.func.isRequired, - }; - - constructor() { - super(); - - this._onViewCommunityClick = this._onViewCommunityClick.bind(this); - this._onRemoveClick = this._onRemoveClick.bind(this); - } - - _onViewCommunityClick() { - dis.dispatch({ - action: 'view_group', - group_id: this.props.tag, - }); - this.props.onFinished(); - } - - _onRemoveClick() { - dis.dispatch(TagOrderActions.removeTag( - // XXX: Context menus don't have a MatrixClient context - MatrixClientPeg.get(), - this.props.tag, - )); - this.props.onFinished(); - } - - render() { - const TintableSvg = sdk.getComponent("elements.TintableSvg"); - return
-
- - { _t('View Community') } -
-
-
- - { _t('Remove') } -
-
; - } -} diff --git a/src/components/views/dialogs/BugReportDialog.js b/src/components/views/dialogs/BugReportDialog.js deleted file mode 100644 index 95b5a6a068..0000000000 --- a/src/components/views/dialogs/BugReportDialog.js +++ /dev/null @@ -1,212 +0,0 @@ -/* -Copyright 2017 OpenMarket 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 sdk from 'matrix-react-sdk'; -import SdkConfig from 'matrix-react-sdk/lib/SdkConfig'; -import Modal from 'matrix-react-sdk/lib/Modal'; -import { _t } from 'matrix-react-sdk/lib/languageHandler'; - -export default class BugReportDialog extends React.Component { - constructor(props, context) { - super(props, context); - this.state = { - sendLogs: true, - busy: false, - err: null, - issueUrl: "", - text: "", - progress: null, - }; - this._unmounted = false; - this._onSubmit = this._onSubmit.bind(this); - this._onCancel = this._onCancel.bind(this); - this._onTextChange = this._onTextChange.bind(this); - this._onIssueUrlChange = this._onIssueUrlChange.bind(this); - this._onSendLogsChange = this._onSendLogsChange.bind(this); - this._sendProgressCallback = this._sendProgressCallback.bind(this); - } - - componentWillUnmount() { - this._unmounted = true; - } - - _onCancel(ev) { - this.props.onFinished(false); - } - - _onSubmit(ev) { - const userText = - (this.state.text.length > 0 ? this.state.text + '\n\n': '') + 'Issue: ' + - (this.state.issueUrl.length > 0 ? this.state.issueUrl : 'No issue link given'); - - this.setState({ busy: true, progress: null, err: null }); - this._sendProgressCallback(_t("Preparing to send logs")); - - require(['../../../vector/submit-rageshake'], (s) => { - s(SdkConfig.get().bug_report_endpoint_url, { - userText, - sendLogs: true, - progressCallback: this._sendProgressCallback, - }).then(() => { - if (!this._unmounted) { - this.props.onFinished(false); - const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - Modal.createTrackedDialog('Bug report sent', '', QuestionDialog, { - title: _t('Logs sent'), - description: _t('Thank you!'), - hasCancelButton: false, - }); - } - }, (err) => { - if (!this._unmounted) { - this.setState({ - busy: false, - progress: null, - err: _t("Failed to send logs: ") + `${err.message}`, - }); - } - }); - }); - } - - _onTextChange(ev) { - this.setState({ text: ev.target.value }); - } - - _onIssueUrlChange(ev) { - this.setState({ issueUrl: ev.target.value }); - } - - _onSendLogsChange(ev) { - this.setState({ sendLogs: ev.target.checked }); - } - - _sendProgressCallback(progress) { - if (this._unmounted) { - return; - } - this.setState({progress: progress}); - } - - render() { - const Loader = sdk.getComponent("elements.Spinner"); - - let error = null; - if (this.state.err) { - error =
- {this.state.err} -
; - } - - let cancelButton = null; - if (!this.state.busy) { - cancelButton = ; - } - - let progress = null; - if (this.state.busy) { - progress = ( -
- - {this.state.progress} ... -
- ); - } - - return ( -
-
- { _t("Submit debug logs") } -
-
-

- { _t( - "Debug logs contain application usage data including your " + - "username, the IDs or aliases of the rooms or groups you " + - "have visited and the usernames of other users. They do " + - "not contain messages.", - ) } -

-

- { _t( - "Click here to create a GitHub issue.", - {}, - { - a: (sub) => - { sub } - , - }, - ) } -

-
- - -
-
- -