diff --git a/res/flags/AD.png b/res/flags/AD.png
deleted file mode 100644
index d5d59645..00000000
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 05c7418a..00000000
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 bc7cef09..00000000
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 d48facad..00000000
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 8fd27cd3..00000000
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 883835ff..00000000
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 b1bb36b9..00000000
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 ae68b12c..00000000
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 146e9c0a..00000000
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 8142adfc..00000000
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 cc5bf30d..00000000
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 e32414bd..00000000
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 8d1e1437..00000000
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 6ec17884..00000000
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 ba269c04..00000000
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 2bf3c746..00000000
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 3e3ec3fc..00000000
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 694050ca..00000000
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 6de2cde8..00000000
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 742ba923..00000000
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 17f9f67d..00000000
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 b01d3ff5..00000000
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 d0f82e82..00000000
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 21865ac7..00000000
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 a7c60914..00000000
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 6d50a0f5..00000000
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 310a25ea..00000000
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 bc4da8d9..00000000
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 144b8d32..00000000
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 08979437..00000000
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 02784925..00000000
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 2b05a8fc..00000000
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 1f031df0..00000000
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 aafb0f17..00000000
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 30840167..00000000
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 ce9de9c9..00000000
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 33620c3f..00000000
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 4bbf8b11..00000000
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 fd40fc8a..00000000
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 230aacd4..00000000
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 c58ed4f7..00000000
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 6c2441e3..00000000
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 9fd87167..00000000
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 9741b9b1..00000000
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 6cca3596..00000000
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 13b993d1..00000000
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 bca5730f..00000000
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 e086855c..00000000
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 65c0aba4..00000000
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 b351c67a..00000000
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 e7a25c60..00000000
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 f249bbaa..00000000
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 e02cacd3..00000000
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 3ea21422..00000000
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 3182f48b..00000000
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 54623346..00000000
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 93e26916..00000000
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 243bb739..00000000
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 fc74cc39..00000000
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 c3a0e9d1..00000000
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 5c4a004f..00000000
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 1589d0cc..00000000
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 4c53dead..00000000
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 3668de79..00000000
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 66ec709d..00000000
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 148be93c..00000000
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 7cb84415..00000000
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 aae73b6f..00000000
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 7b420f02..00000000
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 42f64bf3..00000000
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 cecc683c..00000000
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 6074fea0..00000000
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 45fdb664..00000000
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 d8fd75c6..00000000
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 6d50a0f5..00000000
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 3808a61f..00000000
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 589be700..00000000
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 babe1e4c..00000000
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 d34cddec..00000000
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 98828a59..00000000
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 aec8969b..00000000
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 70b1a623..00000000
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 9aa58327..00000000
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 cf1645c2..00000000
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 ec374fb3..00000000
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 46874b4d..00000000
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 81b7abdf..00000000
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 7fd1015e..00000000
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 101de51e..00000000
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 772c2cbe..00000000
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 d5bd8c1e..00000000
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 8923085d..00000000
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 20c268ce..00000000
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 86f56635..00000000
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 907dc596..00000000
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 8d1e1437..00000000
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 4cf8c311..00000000
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 413ceb15..00000000
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 097abeb4..00000000
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 23499bf6..00000000
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 80200657..00000000
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 63f22201..00000000
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 02688263..00000000
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 c777acc4..00000000
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 85fa9bfe..00000000
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 1675d8e7..00000000
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 f2c21f72..00000000
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 0b8e6750..00000000
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 5ee3e63c..00000000
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 53b967be..00000000
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 a1437aba..00000000
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 0d462fa3..00000000
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 8934db7e..00000000
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 6f92d523..00000000
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 866b3f15..00000000
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 56b433c7..00000000
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 e1ddd5f8..00000000
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 8b7c54bc..00000000
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 227a3b33..00000000
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 bc6189be..00000000
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 c92248b9..00000000
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 ab1cb949..00000000
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 0b41c7a5..00000000
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 7af5290d..00000000
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 e10a1255..00000000
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 6ad67d42..00000000
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 865df57a..00000000
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 e83a2d08..00000000
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 57034d36..00000000
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 6e7ad582..00000000
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 46c3b84a..00000000
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 79b505d4..00000000
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 7740cdc0..00000000
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 8f383e67..00000000
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 a0f36d89..00000000
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 2884c4c0..00000000
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 1f76cfc9..00000000
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 06fc2ad1..00000000
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 8e54c2b8..00000000
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 97424d4e..00000000
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 6d50a0f5..00000000
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 28bfccc9..00000000
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 e482a659..00000000
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 84e2e65e..00000000
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 38fec347..00000000
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 70a03c6b..00000000
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 1e1bbe60..00000000
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 3833d683..00000000
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 63119096..00000000
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 9cab441a..00000000
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 c144de17..00000000
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 12217070..00000000
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 7963aa61..00000000
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 d5d4d400..00000000
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 0f2ecb43..00000000
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 d0a5d24f..00000000
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 096cb111..00000000
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 17f18ac5..00000000
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 66be6563..00000000
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 7ecfd317..00000000
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 11126ade..00000000
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 d584fa84..00000000
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 c0540425..00000000
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 73aee15b..00000000
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 fd044933..00000000
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 08979437..00000000
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 aafb0f17..00000000
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 744458e1..00000000
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 58c2afb2..00000000
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 007c99ec..00000000
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 839368dd..00000000
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 63a89336..00000000
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 3515d95d..00000000
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 58f70b8d..00000000
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 2f33f257..00000000
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 c796f587..00000000
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 0d98de03..00000000
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 87f4e2f4..00000000
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 273869df..00000000
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 b74c396d..00000000
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 e34c62d5..00000000
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 8efdb912..00000000
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 7a0cceec..00000000
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 49e29082..00000000
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 6cb2e1e7..00000000
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 a61c42c4..00000000
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 bb091cc8..00000000
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 6d50a0f5..00000000
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 4495d29e..00000000
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 ebb0f28a..00000000
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 64532ffa..00000000
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 64b3cfff..00000000
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 250de6f6..00000000
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 5833c130..00000000
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 ce5248f4..00000000
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 d8711a83..00000000
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 81880931..00000000
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 6f00e579..00000000
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 055dde68..00000000
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 96359834..00000000
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 aafb0f17..00000000
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 84c7021f..00000000
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 c5ed1991..00000000
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 1af1ca28..00000000
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 d0b18435..00000000
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 64e2970b..00000000
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 b072dda8..00000000
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 83933d45..00000000
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 c102721a..00000000
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 80de92e5..00000000
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 dd52215c..00000000
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 78f45b7c..00000000
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 2182f4ff..00000000
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 3e3e19d4..00000000
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 753bec22..00000000
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 6d50a0f5..00000000
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 8501ada6..00000000
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 0c884c32..00000000
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 3c9026fa..00000000
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 fd605749..00000000
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 b4c834b1..00000000
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 d18cb939..00000000
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 21c4b98b..00000000
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 c828206e..00000000
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 f2a5bd22..00000000
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 66d69833..00000000
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 7a127f51..00000000
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 2353ba1b..00000000
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 7949f65d..00000000
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 687e3052..00000000
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 0a21ad15..00000000
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 c3a245b7..00000000
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 21a347c6..00000000
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 643b6ae0..00000000
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 63a13c0e..00000000
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 da991a93..00000000
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 e75e17c9..00000000
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 46f93cad..00000000
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 8c849a73..00000000
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 6ea2122f..00000000
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 bad3ba4d..00000000
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 d94359dc..00000000
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 f8b80e5b..00000000
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 8b9bbd89..00000000
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 32887936..00000000
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 7f0a52d3..00000000
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 87adc3af..00000000
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 742c9f7e..00000000
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 fec27ba4..00000000
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 5d64a7d0..00000000
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 50c34e56..00000000
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 927ce1f6..00000000
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 b87eeda7..00000000
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 adc74437..00000000
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 36200cd8..00000000
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 708213bf..00000000
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 6ee34bf3..00000000
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 7dbfdcd0..00000000
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 3271d5ae..00000000
--- 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 10806f4f..00000000
--- 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 0fc3e025..00000000
--- 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 7cacc14e..00000000
--- 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 39463a67..00000000
--- 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 =
- ;
- }
- }
-
- 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(
-
-
- );
- }
-
- 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 126ae404..00000000
--- 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 = (
-
- );
- }
- 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 =
- );
- }
-});
-
-// 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 ed092d94..00000000
--- 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 =
;
- } 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 (
-
- );
- }
- }
-});
-
-module.exports = RoomSubList;
diff --git a/src/components/structures/SearchBox.js b/src/components/structures/SearchBox.js
deleted file mode 100644
index 2d6e6ae0..00000000
--- 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 3a5d35a5..00000000
--- 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 (
-
- );
- }
-});
diff --git a/src/components/views/context_menus/GenericElementContextMenu.js b/src/components/views/context_menus/GenericElementContextMenu.js
deleted file mode 100644
index 3f4804db..00000000
--- 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 2319fe05..00000000
--- 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 11f14f36..00000000
--- 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 = (
-
- );
- }
-
- 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 = (
-
- );
- }
-
- // 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 = (
-
- );
- },
-});
diff --git a/src/components/views/context_menus/TagTileContextMenu.js b/src/components/views/context_menus/TagTileContextMenu.js
deleted file mode 100644
index 576e8485..00000000
--- 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 95b5a6a0..00000000
--- 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 }
- ,
- },
- ) }
-
-
-
-
-
-
-
-
-
- {progress}
- {error}
-
-
-
-
- {cancelButton}
-
-
- );
- }
-}
-
-BugReportDialog.propTypes = {
- onFinished: React.PropTypes.func.isRequired,
-};
diff --git a/src/components/views/dialogs/ChangelogDialog.js b/src/components/views/dialogs/ChangelogDialog.js
deleted file mode 100644
index 92aeadf8..00000000
--- a/src/components/views/dialogs/ChangelogDialog.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- Copyright 2016 Aviral Dasgupta
-
- 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 request from 'browser-request';
-import { _t } from 'matrix-react-sdk/lib/languageHandler';
-
-const REPOS = ['vector-im/riot-web', 'matrix-org/matrix-react-sdk', 'matrix-org/matrix-js-sdk'];
-
-export default class ChangelogDialog extends React.Component {
- constructor(props) {
- super(props);
-
- this.state = {};
- }
-
- componentDidMount() {
- const version = this.props.newVersion.split('-');
- const version2 = this.props.version.split('-');
- if(version == null || version2 == null) return;
- // parse versions of form: [vectorversion]-react-[react-sdk-version]-js-[js-sdk-version]
- for(let i=0; i {
- if(body == null) return;
- this.setState({[REPOS[i]]: JSON.parse(body).commits});
- });
- }
- }
-
- _elementsForCommit(commit) {
- return (
-
;
- }
-
- const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
- return (
-
- { body }
-
- );
- }
-}
diff --git a/src/components/views/dialogs/SetPasswordDialog.js b/src/components/views/dialogs/SetPasswordDialog.js
deleted file mode 100644
index b82d0346..00000000
--- a/src/components/views/dialogs/SetPasswordDialog.js
+++ /dev/null
@@ -1,137 +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.
-*/
-
-import React from 'react';
-import sdk from 'matrix-react-sdk';
-import { _t } from 'matrix-react-sdk/lib/languageHandler';
-import Modal from 'matrix-react-sdk/lib/Modal';
-
-const WarmFuzzy = function(props) {
- const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
- let title = _t('You have successfully set a password!');
- if (props.didSetEmail) {
- title = _t('You have successfully set a password and an email address!');
- }
- const advice = _t('You can now return to your account after signing out, and sign in on other devices.');
- let extraAdvice = null;
- if (!props.didSetEmail) {
- extraAdvice = _t('Remember, you can always set an email address in user settings if you change your mind.');
- }
-
- return
-
- { _t('This will allow you to return to your account after signing out, and sign in on other devices.') }
-
-
-
- { this.state.error }
-
-
-
- );
- },
-});
diff --git a/src/components/views/directory/NetworkDropdown.js b/src/components/views/directory/NetworkDropdown.js
deleted file mode 100644
index 9c19cdbc..00000000
--- a/src/components/views/directory/NetworkDropdown.js
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
-Copyright 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.
-*/
-
-import React from 'react';
-import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg';
-import {instanceForInstanceId} from '../../../utils/DirectoryUtils';
-
-const DEFAULT_ICON_URL = "img/network-matrix.svg";
-
-export default class NetworkDropdown extends React.Component {
- constructor(props) {
- super(props);
-
- this.dropdownRootElement = null;
- this.ignoreEvent = null;
-
- this.onInputClick = this.onInputClick.bind(this);
- this.onRootClick = this.onRootClick.bind(this);
- this.onDocumentClick = this.onDocumentClick.bind(this);
- this.onMenuOptionClick = this.onMenuOptionClick.bind(this);
- this.onInputKeyUp = this.onInputKeyUp.bind(this);
- this.collectRoot = this.collectRoot.bind(this);
- this.collectInputTextBox = this.collectInputTextBox.bind(this);
-
- this.inputTextBox = null;
-
- const server = MatrixClientPeg.getHomeServerName();
- this.state = {
- expanded: false,
- selectedServer: server,
- selectedInstance: null,
- includeAllNetworks: false,
- };
- }
-
- componentWillMount() {
- // Listen for all clicks on the document so we can close the
- // menu when the user clicks somewhere else
- document.addEventListener('click', this.onDocumentClick, false);
-
- // fire this now so the defaults can be set up
- this.props.onOptionChange(this.state.selectedServer, this.state.selectedInstance, this.state.includeAllNetworks);
- }
-
- componentWillUnmount() {
- document.removeEventListener('click', this.onDocumentClick, false);
- }
-
- componentDidUpdate() {
- if (this.state.expanded && this.inputTextBox) {
- this.inputTextBox.focus();
- }
- }
-
- onDocumentClick(ev) {
- // Close the dropdown if the user clicks anywhere that isn't
- // within our root element
- if (ev !== this.ignoreEvent) {
- this.setState({
- expanded: false,
- });
- }
- }
-
- onRootClick(ev) {
- // This captures any clicks that happen within our elements,
- // such that we can then ignore them when they're seen by the
- // click listener on the document handler, ie. not close the
- // dropdown immediately after opening it.
- // NB. We can't just stopPropagation() because then the event
- // doesn't reach the React onClick().
- this.ignoreEvent = ev;
- }
-
- onInputClick(ev) {
- this.setState({
- expanded: !this.state.expanded,
- });
- ev.preventDefault();
- }
-
- onMenuOptionClick(server, instance, includeAll) {
- this.setState({
- expanded: false,
- selectedServer: server,
- selectedInstanceId: instance ? instance.instance_id : null,
- includeAll: includeAll,
- });
- this.props.onOptionChange(server, instance ? instance.instance_id : null, includeAll);
- }
-
- onInputKeyUp(e) {
- if (e.key == 'Enter') {
- this.setState({
- expanded: false,
- selectedServer: e.target.value,
- selectedNetwork: null,
- });
- this.props.onOptionChange(e.target.value, null);
- }
- }
-
- collectRoot(e) {
- if (this.dropdownRootElement) {
- this.dropdownRootElement.removeEventListener('click', this.onRootClick, false);
- }
- if (e) {
- e.addEventListener('click', this.onRootClick, false);
- }
- this.dropdownRootElement = e;
- }
-
- collectInputTextBox(e) {
- this.inputTextBox = e;
- }
-
- _getMenuOptions() {
- const options = [];
-
- let servers = [];
- if (this.props.config.servers) {
- servers = servers.concat(this.props.config.servers);
- }
-
- if (servers.indexOf(MatrixClientPeg.getHomeServerName()) == -1) {
- servers.unshift(MatrixClientPeg.getHomeServerName());
- }
-
- // For our own HS, we can use the instance_ids given in the third party protocols
- // response to get the server to filter the room list by network for us.
- // We can't get thirdparty protocols for remote server yet though, so for those
- // we can only show the default room list.
- for (const server of servers) {
- options.push(this._makeMenuOption(server, null, true));
- if (server == MatrixClientPeg.getHomeServerName()) {
- options.push(this._makeMenuOption(server, null, false));
- if (this.props.protocols) {
- for (const proto of Object.keys(this.props.protocols)) {
- if (!this.props.protocols[proto].instances) continue;
-
- const sortedInstances = this.props.protocols[proto].instances;
- sortedInstances.sort(function(x, y) {
- const a = x.desc
- const b = y.desc
- if (a < b) {
- return -1;
- } else if (a > b) {
- return 1;
- } else {
- return 0;
- }
- });
-
- for (const instance of sortedInstances) {
- if (!instance.instance_id) continue;
- options.push(this._makeMenuOption(server, instance, false));
- }
- }
- }
- }
- }
-
- return options;
- }
-
- _makeMenuOption(server, instance, includeAll, handleClicks) {
- if (handleClicks === undefined) handleClicks = true;
-
- let icon;
- let name;
- let span_class;
- let key;
-
- if (!instance && includeAll) {
- key = server;
- name = server;
- span_class = 'mx_NetworkDropdown_menu_all';
- } else if (!instance) {
- key = server + '_all';
- name = 'Matrix';
- icon = ;
- span_class = 'mx_NetworkDropdown_menu_network';
- } else {
- key = server + '_inst_' + instance.instance_id;
- const imgUrl = instance.icon ?
- MatrixClientPeg.get().mxcUrlToHttp(instance.icon, 25, 25, 'crop', true) :
- DEFAULT_ICON_URL;
- icon = ;
- name = instance.desc;
- span_class = 'mx_NetworkDropdown_menu_network';
- }
-
- const click_handler = handleClicks ? this.onMenuOptionClick.bind(this, server, instance, includeAll) : null;
-
- return
- {icon}
- {name}
-
- }
-
- render() {
- let current_value;
-
- let menu;
- if (this.state.expanded) {
- const menu_options = this._getMenuOptions();
- menu =
;
- }
-}
-
-NetworkDropdown.propTypes = {
- onOptionChange: React.PropTypes.func.isRequired,
- protocols: React.PropTypes.object,
- // The room directory config. May have a 'servers' key that is a list of server names to include in the dropdown
- config: React.PropTypes.object,
-};
-
-NetworkDropdown.defaultProps = {
- protocols: {},
- config: {},
-};
diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js
deleted file mode 100644
index d1a34d02..00000000
--- a/src/components/views/elements/ImageView.js
+++ /dev/null
@@ -1,205 +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');
-
-import {formatDate} from 'matrix-react-sdk/lib/DateUtils';
-var filesize = require('filesize');
-var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton');
-const Modal = require('matrix-react-sdk/lib/Modal');
-const sdk = require('matrix-react-sdk');
-import { _t } from 'matrix-react-sdk/lib/languageHandler';
-
-module.exports = React.createClass({
- displayName: 'ImageView',
-
- propTypes: {
- src: React.PropTypes.string.isRequired, // the source of the image being displayed
- name: React.PropTypes.string, // the main title ('name') for the image
- link: React.PropTypes.string, // the link (if any) applied to the name of the image
- width: React.PropTypes.number, // width of the image src in pixels
- height: React.PropTypes.number, // height of the image src in pixels
- fileSize: React.PropTypes.number, // size of the image src in bytes
- onFinished: React.PropTypes.func.isRequired, // callback when the lightbox is dismissed
-
- // the event (if any) that the Image is displaying. Used for event-specific stuff like
- // redactions, senders, timestamps etc. Other descriptors are taken from the explicit
- // properties above, which let us use lightboxes to display images which aren't associated
- // with events.
- mxEvent: React.PropTypes.object,
- },
-
- // XXX: keyboard shortcuts for managing dialogs should be done by the modal
- // dialog base class somehow, surely...
- 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();
- }
- },
-
- onRedactClick: function() {
- const ConfirmRedactDialog = sdk.getComponent("dialogs.ConfirmRedactDialog");
- Modal.createTrackedDialog('Confirm Redact Dialog', 'Image View', ConfirmRedactDialog, {
- onFinished: (proceed) => {
- if (!proceed) return;
- var self = this;
- MatrixClientPeg.get().redactEvent(
- this.props.mxEvent.getRoomId(), this.props.mxEvent.getId()
- ).catch(function(e) {
- var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
- // display error message stating you couldn't delete this.
- var code = e.errcode || e.statusCode;
- Modal.createTrackedDialog('You cannot delete this image.', '', ErrorDialog, {
- title: _t('Error'),
- description: _t('You cannot delete this image. (%(code)s)', {code: code})
- });
- }).done();
- }
- });
- },
-
- getName: function () {
- var name = this.props.name;
- if (name && this.props.link) {
- name = { name };
- }
- return name;
- },
-
- render: function() {
-
-/*
- // In theory max-width: 80%, max-height: 80% on the CSS should work
- // but in practice, it doesn't, so do it manually:
-
- var width = this.props.width || 500;
- var height = this.props.height || 500;
-
- var maxWidth = document.documentElement.clientWidth * 0.8;
- var maxHeight = document.documentElement.clientHeight * 0.8;
-
- var widthFrac = width / maxWidth;
- var heightFrac = height / maxHeight;
-
- var displayWidth;
- var displayHeight;
- if (widthFrac > heightFrac) {
- displayWidth = Math.min(width, maxWidth);
- displayHeight = (displayWidth / width) * height;
- } else {
- displayHeight = Math.min(height, maxHeight);
- displayWidth = (displayHeight / height) * width;
- }
-
- var style = {
- width: displayWidth,
- height: displayHeight
- };
-*/
- var style, res;
-
- if (this.props.width && this.props.height) {
- style = {
- width: this.props.width,
- height: this.props.height,
- };
- res = style.width + "x" + style.height + "px";
- }
-
- var size;
- if (this.props.fileSize) {
- size = filesize(this.props.fileSize);
- }
-
- var size_res;
- if (size && res) {
- size_res = size + ", " + res;
- }
- else {
- size_res = size || res;
- }
-
- var showEventMeta = !!this.props.mxEvent;
-
- var eventMeta;
- if(showEventMeta) {
- // Figure out the sender, defaulting to mxid
- let sender = this.props.mxEvent.getSender();
- const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
- if (room) {
- const member = room.getMember(sender);
- if (member) sender = member.name;
- }
-
- eventMeta = (
- { _t('Uploaded on %(date)s by %(user)s', {date: formatDate(new Date(this.props.mxEvent.getTs())), user: sender}) }
-
- );
- }
-});
diff --git a/src/components/views/elements/InlineSpinner.js b/src/components/views/elements/InlineSpinner.js
deleted file mode 100644
index adb916fc..00000000
--- a/src/components/views/elements/InlineSpinner.js
+++ /dev/null
@@ -1,33 +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.
-*/
-
-const React = require('react');
-
-module.exports = React.createClass({
- displayName: 'InlineSpinner',
-
- render: function() {
- var w = this.props.w || 16;
- var h = this.props.h || 16;
- var imgClass = this.props.imgClassName || "";
-
- return (
-
-
-
- );
- }
-});
diff --git a/src/components/views/elements/Spinner.js b/src/components/views/elements/Spinner.js
deleted file mode 100644
index 2b620f12..00000000
--- a/src/components/views/elements/Spinner.js
+++ /dev/null
@@ -1,34 +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');
-
-module.exports = React.createClass({
- displayName: 'Spinner',
-
- render: function() {
- var w = this.props.w || 32;
- var h = this.props.h || 32;
- var imgClass = this.props.imgClassName || "";
- return (
-
-
-
- );
- }
-});
diff --git a/src/components/views/elements/SyntaxHighlight.js b/src/components/views/elements/SyntaxHighlight.js
deleted file mode 100644
index 82b5ae57..00000000
--- a/src/components/views/elements/SyntaxHighlight.js
+++ /dev/null
@@ -1,53 +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.
-*/
-
-import React from 'react';
-import PropTypes from 'prop-types';
-import {highlightBlock} from 'highlight.js';
-
-export default class SyntaxHighlight extends React.Component {
- static propTypes = {
- className: PropTypes.string,
- children: PropTypes.node,
- };
-
- constructor(props, context) {
- super(props, context);
-
- this._ref = this._ref.bind(this);
- }
-
- // componentDidUpdate used here for reusability
- // componentWillReceiveProps fires too early to call highlightBlock on.
- componentDidUpdate() {
- if (this._el) highlightBlock(this._el);
- }
-
- // call componentDidUpdate because _ref is fired on initial render
- // which does not fire componentDidUpdate
- _ref(el) {
- this._el = el;
- this.componentDidUpdate();
- }
-
- render() {
- const { className, children } = this.props;
-
- return
- { children }
-
;
- }
-}
diff --git a/src/components/views/globals/MatrixToolbar.js b/src/components/views/globals/MatrixToolbar.js
deleted file mode 100644
index 06bfa36e..00000000
--- a/src/components/views/globals/MatrixToolbar.js
+++ /dev/null
@@ -1,46 +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 Notifier from 'matrix-react-sdk/lib/Notifier';
-import AccessibleButton from 'matrix-react-sdk/lib/components/views/elements/AccessibleButton';
-
-module.exports = React.createClass({
- displayName: 'MatrixToolbar',
-
- hideToolbar: function() {
- Notifier.setToolbarHidden(true);
- },
-
- onClick: function() {
- Notifier.setEnabled(true);
- },
-
- render: function() {
- return (
-
- );
- },
-});
diff --git a/src/components/views/globals/NewVersionBar.js b/src/components/views/globals/NewVersionBar.js
deleted file mode 100644
index 2aedf392..00000000
--- a/src/components/views/globals/NewVersionBar.js
+++ /dev/null
@@ -1,107 +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 sdk from 'matrix-react-sdk';
-import Modal from 'matrix-react-sdk/lib/Modal';
-import PlatformPeg from 'matrix-react-sdk/lib/PlatformPeg';
-import { _t } from 'matrix-react-sdk/lib/languageHandler';
-
-/**
- * Check a version string is compatible with the Changelog
- * dialog ([vectorversion]-react-[react-sdk-version]-js-[js-sdk-version])
- */
-function checkVersion(ver) {
- const parts = ver.split('-');
- return parts.length == 5 && parts[1] == 'react' && parts[3] == 'js';
-}
-
-export default React.createClass({
- propTypes: {
- version: React.PropTypes.string.isRequired,
- newVersion: React.PropTypes.string.isRequired,
- releaseNotes: React.PropTypes.string,
- },
-
- displayReleaseNotes: function(releaseNotes) {
- const QuestionDialog = sdk.getComponent('dialogs.QuestionDialog');
- Modal.createTrackedDialog('Display release notes', '', QuestionDialog, {
- title: _t("What's New"),
- description:
{releaseNotes}
,
- button: _t("Update"),
- onFinished: (update) => {
- if(update && PlatformPeg.get()) {
- PlatformPeg.get().installUpdate();
- }
- }
- });
- },
-
- displayChangelog: function() {
- const ChangelogDialog = sdk.getComponent('dialogs.ChangelogDialog');
- Modal.createTrackedDialog('Display Changelog', '', ChangelogDialog, {
- version: this.props.version,
- newVersion: this.props.newVersion,
- onFinished: (update) => {
- if(update && PlatformPeg.get()) {
- PlatformPeg.get().installUpdate();
- }
- }
- });
- },
-
- onUpdateClicked: function() {
- PlatformPeg.get().installUpdate();
- },
-
- render: function() {
- let action_button;
- // If we have release notes to display, we display them. Otherwise,
- // we display the Changelog Dialog which takes two versions and
- // automatically tells you what's changed (provided the versions
- // are in the right format)
- if (this.props.releaseNotes) {
- action_button = (
-
- );
- } else if (checkVersion(this.props.version) && checkVersion(this.props.newVersion)) {
- action_button = (
-
- );
- } else if (PlatformPeg.get()) {
- action_button = (
-
- );
- }
- return (
-
-
-
- {_t("A new version of Riot is available.")}
-
- {action_button}
-
- );
- }
-});
diff --git a/src/components/views/globals/PasswordNagBar.js b/src/components/views/globals/PasswordNagBar.js
deleted file mode 100644
index a04d48e0..00000000
--- a/src/components/views/globals/PasswordNagBar.js
+++ /dev/null
@@ -1,64 +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';
-
-import React from 'react';
-import sdk from 'matrix-react-sdk';
-import Modal from 'matrix-react-sdk/lib/Modal';
-import dis from 'matrix-react-sdk/lib/dispatcher';
-import { _t } from 'matrix-react-sdk/lib/languageHandler';
-
-export default React.createClass({
- onUpdateClicked: function() {
- const SetPasswordDialog = sdk.getComponent('dialogs.SetPasswordDialog');
- Modal.createTrackedDialog('Set Password Dialog', 'Password Nag Bar', SetPasswordDialog, {
- onFinished: (passwordChanged) => {
- if (!passwordChanged) {
- return;
- }
- // Notify SessionStore that the user's password was changed
- dis.dispatch({
- action: 'password_changed',
- });
- },
- });
- },
-
- render: function() {
- const toolbarClasses = "mx_MatrixToolbar mx_MatrixToolbar_clickable";
- return (
-
-
-
- { _t(
- "To return to your account in future you need to set a password",
- {},
- { 'u': (sub) => { sub } },
- ) }
-
-
-
- );
- },
-});
diff --git a/src/components/views/globals/UpdateCheckBar.js b/src/components/views/globals/UpdateCheckBar.js
deleted file mode 100644
index 926ccbcc..00000000
--- a/src/components/views/globals/UpdateCheckBar.js
+++ /dev/null
@@ -1,85 +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 { _t } from 'matrix-react-sdk/lib/languageHandler';
-import PlatformPeg from 'matrix-react-sdk/lib/PlatformPeg';
-import {updateCheckStatusEnum} from '../../../vector/platform/VectorBasePlatform';
-import AccessibleButton from 'matrix-react-sdk/lib/components/views/elements/AccessibleButton';
-
-const doneStatuses = [
- updateCheckStatusEnum.ERROR,
- updateCheckStatusEnum.NOTAVAILABLE,
-];
-
-export default React.createClass({
- propTypes: {
- status: React.PropTypes.oneOf(Object.values(updateCheckStatusEnum)).isRequired,
- // Currently for error detail but will be usable for download progress
- // once that is a thing that squirrel passes through electron.
- detail: React.PropTypes.string,
- },
-
- getDefaultProps: function() {
- return {
- detail: '',
- }
- },
-
- getStatusText: function() {
- switch(this.props.status) {
- case updateCheckStatusEnum.ERROR:
- return _t('Error encountered (%(errorDetail)s).', { errorDetail: this.props.detail });
- case updateCheckStatusEnum.CHECKING:
- return _t('Checking for an update...');
- case updateCheckStatusEnum.NOTAVAILABLE:
- return _t('No update available.');
- case updateCheckStatusEnum.DOWNLOADING:
- return _t('Downloading update...');
- }
- }
- ,
-
- hideToolbar: function() {
- PlatformPeg.get().stopUpdateCheck();
- },
-
- render: function() {
- const message = this.getStatusText();
- const warning = _t('Warning');
-
- let image;
- if (doneStatuses.includes(this.props.status)) {
- image = ;
- } else {
- image = ;
- }
-
- return (
-
- {image}
-
- {message}
-
-
-
-
-
- );
- }
-});
diff --git a/src/components/views/messages/DateSeparator.js b/src/components/views/messages/DateSeparator.js
deleted file mode 100644
index 2e081bc6..00000000
--- a/src/components/views/messages/DateSeparator.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-Copyright 2015, 2016 OpenMarket Ltd
-Copyright 2018 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.
-*/
-
-import React from 'react';
-import PropTypes from 'prop-types';
-import { _t } from 'matrix-react-sdk/lib/languageHandler';
-import {formatFullDateNoTime} from 'matrix-react-sdk/lib/DateUtils';
-
-function getdaysArray() {
- return [
- _t('Sunday'),
- _t('Monday'),
- _t('Tuesday'),
- _t('Wednesday'),
- _t('Thursday'),
- _t('Friday'),
- _t('Saturday'),
- ];
-}
-
-export default class DateSeparator extends React.Component {
- static propTypes = {
- ts: PropTypes.number.isRequired,
- };
-
- getLabel() {
- const date = new Date(this.props.ts);
- const today = new Date();
- const yesterday = new Date();
- const days = getdaysArray();
- yesterday.setDate(today.getDate() - 1);
-
- if (date.toDateString() === today.toDateString()) {
- return _t('Today');
- } else if (date.toDateString() === yesterday.toDateString()) {
- return _t('Yesterday');
- } else if (today.getTime() - date.getTime() < 6 * 24 * 60 * 60 * 1000) {
- return days[date.getDay()];
- } else {
- return formatFullDateNoTime(date);
- }
- }
-
- render() {
- return
{ this.getLabel() }
;
- }
-}
diff --git a/src/components/views/messages/MessageTimestamp.js b/src/components/views/messages/MessageTimestamp.js
deleted file mode 100644
index 6d433067..00000000
--- a/src/components/views/messages/MessageTimestamp.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-Copyright 2015, 2016 OpenMarket Ltd
-Copyright 2018 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.
-*/
-
-import React from 'react';
-import PropTypes from 'prop-types';
-import {formatFullDate, formatTime} from 'matrix-react-sdk/lib/DateUtils';
-
-export default class MessageTimestamp extends React.Component {
- static propTypes = {
- ts: PropTypes.number.isRequired,
- showTwelveHour: PropTypes.bool,
- };
-
- render() {
- const date = new Date(this.props.ts);
- return (
-
- { formatTime(date, this.props.showTwelveHour) }
-
- );
- }
-}
diff --git a/src/components/views/rooms/DNDRoomTile.js b/src/components/views/rooms/DNDRoomTile.js
deleted file mode 100644
index d32ecbbb..00000000
--- a/src/components/views/rooms/DNDRoomTile.js
+++ /dev/null
@@ -1,65 +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.
-*/
-
-import React from 'react';
-import { Draggable } from 'react-beautiful-dnd';
-import RoomTile from 'matrix-react-sdk/lib/components/views/rooms/RoomTile';
-
-import classNames from 'classnames';
-
-export default class DNDRoomTile extends React.PureComponent {
- constructor() {
- super();
- this.getClassName = this.getClassName.bind(this);
- }
-
- getClassName(isDragging) {
- return classNames({
- "mx_DNDRoomTile": true,
- "mx_DNDRoomTile_dragging": isDragging,
- });
- }
-
- render() {
- const props = this.props;
-
- return
-
- { (provided, snapshot) => {
- return (
-
-
-
-
-
-
- { provided.placeholder }
-
- );
- } }
-
-
;
- }
-}
diff --git a/src/components/views/rooms/RoomDropTarget.js b/src/components/views/rooms/RoomDropTarget.js
deleted file mode 100644
index 3cb10630..00000000
--- a/src/components/views/rooms/RoomDropTarget.js
+++ /dev/null
@@ -1,35 +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');
-
-module.exports = React.createClass({
- displayName: 'RoomDropTarget',
-
- render: function() {
- return (
-
-
-
- { this.props.label }
-
-
-
- );
- }
-});
diff --git a/src/components/views/rooms/RoomTooltip.js b/src/components/views/rooms/RoomTooltip.js
deleted file mode 100644
index 39d8958d..00000000
--- a/src/components/views/rooms/RoomTooltip.js
+++ /dev/null
@@ -1,120 +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 ReactDOM = require('react-dom');
-var dis = require('matrix-react-sdk/lib/dispatcher');
-import classNames from 'classnames';
-
-const MIN_TOOLTIP_HEIGHT = 25;
-
-module.exports = React.createClass({
- displayName: 'RoomTooltip',
-
- propTypes: {
- // Class applied to the element used to position the tooltip
- className: React.PropTypes.string.isRequired,
- // Class applied to the tooltip itself
- tooltipClassName: React.PropTypes.string,
- // The tooltip is derived from either the room name or a label
- room: React.PropTypes.object,
- label: React.PropTypes.node,
- },
-
- // Create a wrapper for the tooltip outside the parent and attach it to the body element
- componentDidMount: function() {
- this.tooltipContainer = document.createElement("div");
- this.tooltipContainer.className = "mx_RoomTileTooltip_wrapper";
- document.body.appendChild(this.tooltipContainer);
- window.addEventListener('scroll', this._renderTooltip, true);
-
- this.parent = ReactDOM.findDOMNode(this).parentNode;
-
- this._renderTooltip();
- },
-
- componentDidUpdate: function() {
- this._renderTooltip();
- },
-
- // Remove the wrapper element, as the tooltip has finished using it
- componentWillUnmount: function() {
- dis.dispatch({
- action: 'view_tooltip',
- tooltip: null,
- parent: null,
- });
-
- ReactDOM.unmountComponentAtNode(this.tooltipContainer);
- document.body.removeChild(this.tooltipContainer);
- window.removeEventListener('scroll', this._renderTooltip, true);
- },
-
- _updatePosition(style) {
- const parentBox = this.parent.getBoundingClientRect();
- let offset = 0;
- if (parentBox.height > MIN_TOOLTIP_HEIGHT) {
- offset = Math.floor((parentBox.height - MIN_TOOLTIP_HEIGHT) / 2);
- }
- style.top = (parentBox.top - 2) + window.pageYOffset + offset;
- style.left = 6 + parentBox.right + window.pageXOffset;
- return style;
- },
-
- _renderTooltip: function() {
- var label = this.props.room ? this.props.room.name : this.props.label;
-
- // Add the parent's position to the tooltips, so it's correctly
- // positioned, also taking into account any window zoom
- // NOTE: The additional 6 pixels for the left position, is to take account of the
- // tooltips chevron
- var parent = ReactDOM.findDOMNode(this).parentNode;
- var style = {};
- style = this._updatePosition(style);
- style.display = "block";
-
- const tooltipClasses = classNames(
- "mx_RoomTooltip", this.props.tooltipClassName,
- );
-
- var tooltip = (
-
-
- { label }
-
- );
-
- // Render the tooltip manually, as we wish it not to be rendered within the parent
- this.tooltip = ReactDOM.render(tooltip, this.tooltipContainer);
-
- // Tell the roomlist about us so it can manipulate us if it wishes
- dis.dispatch({
- action: 'view_tooltip',
- tooltip: this.tooltip,
- parent: parent,
- });
- },
-
- render: function() {
- // Render a placeholder
- return (
-
-
- );
- },
-});
diff --git a/src/components/views/rooms/SearchBar.js b/src/components/views/rooms/SearchBar.js
deleted file mode 100644
index 26bf81e4..00000000
--- a/src/components/views/rooms/SearchBar.js
+++ /dev/null
@@ -1,71 +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 sdk = require('matrix-react-sdk');
-var classNames = require('classnames');
-var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton');
-import { _t } from "matrix-react-sdk/lib/languageHandler";
-
-module.exports = React.createClass({
- displayName: 'SearchBar',
-
- getInitialState: function() {
- return ({
- scope: 'Room'
- });
- },
-
- onThisRoomClick: function() {
- this.setState({ scope: 'Room' });
- },
-
- onAllRoomsClick: function() {
- this.setState({ scope: 'All' });
- },
-
- onSearchChange: function(e) {
- if (e.keyCode === 13) { // on enter...
- this.onSearch();
- }
- if (e.keyCode === 27) { // escape...
- this.props.onCancelClick();
- }
- },
-
- onSearch: function() {
- this.props.onSearch(this.refs.search_term.value, this.state.scope);
- },
-
- render: function() {
- var searchButtonClasses = classNames({ mx_SearchBar_searchButton : true, mx_SearchBar_searching: this.props.searchInProgress });
- var thisRoomClasses = classNames({ mx_SearchBar_button : true, mx_SearchBar_unselected : this.state.scope !== 'Room' });
- var allRoomsClasses = classNames({ mx_SearchBar_button : true, mx_SearchBar_unselected : this.state.scope !== 'All' });
-
- return (
-
-
-
- {_t("This Room")}
- {_t("All Rooms")}
-
-
- );
- }
-});
diff --git a/src/components/views/settings/IntegrationsManager.js b/src/components/views/settings/IntegrationsManager.js
deleted file mode 100644
index 4a2482f6..00000000
--- a/src/components/views/settings/IntegrationsManager.js
+++ /dev/null
@@ -1,63 +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 sdk = require('matrix-react-sdk');
-var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
-var dis = require('matrix-react-sdk/lib/dispatcher');
-
-module.exports = React.createClass({
- displayName: 'IntegrationsManager',
-
- propTypes: {
- src: React.PropTypes.string.isRequired, // the source of the integration manager being embedded
- onFinished: React.PropTypes.func.isRequired, // callback when the lightbox is dismissed
- },
-
- // XXX: keyboard shortcuts for managing dialogs should be done by the modal
- // dialog base class somehow, surely...
- componentDidMount: function() {
- this.dispatcherRef = dis.register(this.onAction);
- document.addEventListener("keydown", this.onKeyDown);
- },
-
- componentWillUnmount: function() {
- dis.unregister(this.dispatcherRef);
- document.removeEventListener("keydown", this.onKeyDown);
- },
-
- onKeyDown: function(ev) {
- if (ev.keyCode == 27) { // escape
- ev.stopPropagation();
- ev.preventDefault();
- this.props.onFinished();
- }
- },
-
- onAction: function(payload) {
- if (payload.action === 'close_scalar') {
- this.props.onFinished();
- }
- },
-
- render: function() {
- return (
-
- );
- }
-});
diff --git a/src/components/views/settings/Notifications.js b/src/components/views/settings/Notifications.js
deleted file mode 100644
index be03b4d7..00000000
--- a/src/components/views/settings/Notifications.js
+++ /dev/null
@@ -1,919 +0,0 @@
-/*
-Copyright 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.
-*/
-
-import React from 'react';
-import Promise from 'bluebird';
-import sdk from 'matrix-react-sdk';
-import { _t } from 'matrix-react-sdk/lib/languageHandler';
-import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg';
-import UserSettingsStore from 'matrix-react-sdk/lib/UserSettingsStore';
-import SettingsStore, {SettingLevel} from "matrix-react-sdk/lib/settings/SettingsStore";
-import Modal from 'matrix-react-sdk/lib/Modal';
-import {
- NotificationUtils,
- VectorPushRulesDefinitions,
- PushRuleVectorState,
- ContentRules
-} from '../../../notifications';
-
-// TODO: this "view" component still has far too much application logic in it,
-// which should be factored out to other files.
-
-// TODO: this component also does a lot of direct poking into this.state, which
-// is VERY NAUGHTY.
-
-
-/**
- * Rules that Vector used to set in order to override the actions of default rules.
- * These are used to port peoples existing overrides to match the current API.
- * These can be removed and forgotten once everyone has moved to the new client.
- */
-const LEGACY_RULES = {
- "im.vector.rule.contains_display_name": ".m.rule.contains_display_name",
- "im.vector.rule.room_one_to_one": ".m.rule.room_one_to_one",
- "im.vector.rule.room_message": ".m.rule.message",
- "im.vector.rule.invite_for_me": ".m.rule.invite_for_me",
- "im.vector.rule.call": ".m.rule.call",
- "im.vector.rule.notices": ".m.rule.suppress_notices"
-};
-
-function portLegacyActions(actions) {
- const decoded = NotificationUtils.decodeActions(actions);
- if (decoded !== null) {
- return NotificationUtils.encodeActions(decoded);
- } else {
- // We don't recognise one of the actions here, so we don't try to
- // canonicalise them.
- return actions;
- }
-}
-
-module.exports = React.createClass({
- displayName: 'Notifications',
-
- phases: {
- LOADING: "LOADING", // The component is loading or sending data to the hs
- DISPLAY: "DISPLAY", // The component is ready and display data
- ERROR: "ERROR" // There was an error
- },
-
- propTypes: {
- // The array of threepids from the JS SDK (required for email notifications)
- threepids: React.PropTypes.array.isRequired,
- // The brand string set when creating an email pusher
- brand: React.PropTypes.string,
- },
-
- getDefaultProps: function() {
- return {
- threepids: []
- };
- },
-
- getInitialState: function() {
- return {
- phase: this.phases.LOADING,
- masterPushRule: undefined, // The master rule ('.m.rule.master')
- vectorPushRules: [], // HS default push rules displayed in Vector UI
- vectorContentRules: { // Keyword push rules displayed in Vector UI
- vectorState: PushRuleVectorState.ON,
- rules: []
- },
- externalPushRules: [], // Push rules (except content rule) that have been defined outside Vector UI
- externalContentRules: [] // Keyword push rules that have been defined outside Vector UI
- };
- },
-
- componentWillMount: function() {
- this._refreshFromServer();
- },
-
- onEnableNotificationsChange: function(event) {
- const self = this;
- this.setState({
- phase: this.phases.LOADING
- });
-
- MatrixClientPeg.get().setPushRuleEnabled('global', self.state.masterPushRule.kind, self.state.masterPushRule.rule_id, !event.target.checked).done(function() {
- self._refreshFromServer();
- });
- },
-
- onEnableDesktopNotificationsChange: function(event) {
- SettingsStore.setValue(
- "notificationsEnabled", null,
- SettingLevel.DEVICE,
- event.target.checked,
- ).finally(() => {
- this.forceUpdate();
- });
- },
-
- onEnableDesktopNotificationBodyChange: function(event) {
- SettingsStore.setValue(
- "notificationBodyEnabled", null,
- SettingLevel.DEVICE,
- event.target.checked,
- ).finally(() => {
- this.forceUpdate();
- });
- },
-
- onEnableAudioNotificationsChange: function(event) {
- SettingsStore.setValue(
- "audioNotificationsEnabled", null,
- SettingLevel.DEVICE,
- event.target.checked,
- ).finally(() => {
- this.forceUpdate();
- });
- },
-
- onEnableEmailNotificationsChange: function(address, event) {
- let emailPusherPromise;
- if (event.target.checked) {
- const data = {}
- data['brand'] = this.props.brand || 'Riot';
- emailPusherPromise = UserSettingsStore.addEmailPusher(address, data);
- } else {
- const emailPusher = UserSettingsStore.getEmailPusher(this.state.pushers, address);
- emailPusher.kind = null;
- emailPusherPromise = MatrixClientPeg.get().setPusher(emailPusher);
- }
- emailPusherPromise.done(() => {
- this._refreshFromServer();
- }, (error) => {
- const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
- Modal.createTrackedDialog('Error saving email notification preferences', '', ErrorDialog, {
- title: _t('Error saving email notification preferences'),
- description: _t('An error occurred whilst saving your email notification preferences.'),
- });
- });
- },
-
- onNotifStateButtonClicked: function(event) {
- // FIXME: use .bind() rather than className metadata here surely
- const vectorRuleId = event.target.className.split("-")[0];
- const newPushRuleVectorState = event.target.className.split("-")[1];
-
- if ("_keywords" === vectorRuleId) {
- this._setKeywordsPushRuleVectorState(newPushRuleVectorState)
- }
- else {
- const rule = this.getRule(vectorRuleId);
- if (rule) {
- this._setPushRuleVectorState(rule, newPushRuleVectorState);
- }
- }
- },
-
- onKeywordsClicked: function(event) {
- const self = this;
-
- // Compute the keywords list to display
- let keywords = [];
- for (let i in this.state.vectorContentRules.rules) {
- const rule = this.state.vectorContentRules.rules[i];
- keywords.push(rule.pattern);
- }
- if (keywords.length) {
- // As keeping the order of per-word push rules hs side is a bit tricky to code,
- // display the keywords in alphabetical order to the user
- keywords.sort();
-
- keywords = keywords.join(", ");
- }
- else {
- keywords = "";
- }
-
- const TextInputDialog = sdk.getComponent("dialogs.TextInputDialog");
- Modal.createTrackedDialog('Keywords Dialog', '', TextInputDialog, {
- title: _t('Keywords'),
- description: _t('Enter keywords separated by a comma:'),
- button: _t('OK'),
- value: keywords,
- onFinished: function onFinished(should_leave, newValue) {
-
- if (should_leave && newValue !== keywords) {
- let newKeywords = newValue.split(',');
- for (let i in newKeywords) {
- newKeywords[i] = newKeywords[i].trim();
- }
-
- // Remove duplicates and empty
- newKeywords = newKeywords.reduce(function(array, keyword){
- if (keyword !== "" && array.indexOf(keyword) < 0) {
- array.push(keyword);
- }
- return array;
- },[]);
-
- self._setKeywords(newKeywords);
- }
- }
- });
- },
-
- getRule: function(vectorRuleId) {
- for (let i in this.state.vectorPushRules) {
- const rule = this.state.vectorPushRules[i];
- if (rule.vectorRuleId === vectorRuleId) {
- return rule;
- }
- }
- },
-
- _setPushRuleVectorState: function(rule, newPushRuleVectorState) {
- if (rule && rule.vectorState !== newPushRuleVectorState) {
-
- this.setState({
- phase: this.phases.LOADING
- });
-
- const self = this;
- const cli = MatrixClientPeg.get();
- const deferreds = [];
- const ruleDefinition = VectorPushRulesDefinitions[rule.vectorRuleId];
-
- if (rule.rule) {
- const actions = ruleDefinition.vectorStateToActions[newPushRuleVectorState];
-
- if (!actions) {
- // The new state corresponds to disabling the rule.
- deferreds.push(cli.setPushRuleEnabled('global', rule.rule.kind, rule.rule.rule_id, false));
- }
- else {
- // The new state corresponds to enabling the rule and setting specific actions
- deferreds.push(this._updatePushRuleActions(rule.rule, actions, true));
- }
- }
-
- Promise.all(deferreds).done(function() {
- self._refreshFromServer();
- }, function(error) {
- const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
- console.error("Failed to change settings: " + error);
- Modal.createTrackedDialog('Failed to change settings', '', ErrorDialog, {
- title: _t('Failed to change settings'),
- description: ((error && error.message) ? error.message : _t('Operation failed')),
- onFinished: self._refreshFromServer
- });
- });
- }
- },
-
- _setKeywordsPushRuleVectorState: function(newPushRuleVectorState) {
- // Is there really a change?
- if (this.state.vectorContentRules.vectorState === newPushRuleVectorState
- || this.state.vectorContentRules.rules.length === 0) {
- return;
- }
-
- const self = this;
- const cli = MatrixClientPeg.get();
-
- this.setState({
- phase: this.phases.LOADING
- });
-
- // Update all rules in self.state.vectorContentRules
- const deferreds = [];
- for (let i in this.state.vectorContentRules.rules) {
- const rule = this.state.vectorContentRules.rules[i];
-
- let enabled, actions;
- switch (newPushRuleVectorState) {
- case PushRuleVectorState.ON:
- if (rule.actions.length !== 1) {
- actions = PushRuleVectorState.actionsFor(PushRuleVectorState.ON);
- }
-
- if (this.state.vectorContentRules.vectorState === PushRuleVectorState.OFF) {
- enabled = true;
- }
- break;
-
- case PushRuleVectorState.LOUD:
- if (rule.actions.length !== 3) {
- actions = PushRuleVectorState.actionsFor(PushRuleVectorState.LOUD);
- }
-
- if (this.state.vectorContentRules.vectorState === PushRuleVectorState.OFF) {
- enabled = true;
- }
- break;
-
- case PushRuleVectorState.OFF:
- enabled = false;
- break;
- }
-
- if (actions) {
- // Note that the workaround in _updatePushRuleActions will automatically
- // enable the rule
- deferreds.push(this._updatePushRuleActions(rule, actions, enabled));
- }
- else if (enabled != undefined) {
- deferreds.push(cli.setPushRuleEnabled('global', rule.kind, rule.rule_id, enabled));
- }
- }
-
- Promise.all(deferreds).done(function(resps) {
- self._refreshFromServer();
- }, function(error) {
- const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
- console.error("Can't update user notification settings: " + error);
- Modal.createTrackedDialog('Can\'t update user notifcation settings', '', ErrorDialog, {
- title: _t('Can\'t update user notification settings'),
- description: ((error && error.message) ? error.message : _t('Operation failed')),
- onFinished: self._refreshFromServer
- });
- });
- },
-
- _setKeywords: function(newKeywords) {
- this.setState({
- phase: this.phases.LOADING
- });
-
- const self = this;
- const cli = MatrixClientPeg.get();
- const removeDeferreds = [];
-
- // Remove per-word push rules of keywords that are no more in the list
- const vectorContentRulesPatterns = [];
- for (let i in self.state.vectorContentRules.rules) {
- const rule = self.state.vectorContentRules.rules[i];
-
- vectorContentRulesPatterns.push(rule.pattern);
-
- if (newKeywords.indexOf(rule.pattern) < 0) {
- removeDeferreds.push(cli.deletePushRule('global', rule.kind, rule.rule_id));
- }
- }
-
- // If the keyword is part of `externalContentRules`, remove the rule
- // before recreating it in the right Vector path
- for (let i in self.state.externalContentRules) {
- const rule = self.state.externalContentRules[i];
-
- if (newKeywords.indexOf(rule.pattern) >= 0) {
- removeDeferreds.push(cli.deletePushRule('global', rule.kind, rule.rule_id));
- }
- }
-
- const onError = function(error) {
- const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
- console.error("Failed to update keywords: " + error);
- Modal.createTrackedDialog('Failed to update keywords', '', ErrorDialog, {
- title: _t('Failed to update keywords'),
- description: ((error && error.message) ? error.message : _t('Operation failed')),
- onFinished: self._refreshFromServer
- });
- }
-
- // Then, add the new ones
- Promise.all(removeDeferreds).done(function(resps) {
- const deferreds = [];
-
- let pushRuleVectorStateKind = self.state.vectorContentRules.vectorState;
- if (pushRuleVectorStateKind === PushRuleVectorState.OFF) {
- // When the current global keywords rule is OFF, we need to look at
- // the flavor of rules in 'vectorContentRules' to apply the same actions
- // when creating the new rule.
- // Thus, this new rule will join the 'vectorContentRules' set.
- if (self.state.vectorContentRules.rules.length) {
- pushRuleVectorStateKind = PushRuleVectorState.contentRuleVectorStateKind(self.state.vectorContentRules.rules[0]);
- }
- else {
- // ON is default
- pushRuleVectorStateKind = PushRuleVectorState.ON;
- }
- }
-
- for (let i in newKeywords) {
- const keyword = newKeywords[i];
-
- if (vectorContentRulesPatterns.indexOf(keyword) < 0) {
- if (self.state.vectorContentRules.vectorState !== PushRuleVectorState.OFF) {
- deferreds.push(cli.addPushRule
- ('global', 'content', keyword, {
- actions: PushRuleVectorState.actionsFor(pushRuleVectorStateKind),
- pattern: keyword
- }));
- }
- else {
- deferreds.push(self._addDisabledPushRule('global', 'content', keyword, {
- actions: PushRuleVectorState.actionsFor(pushRuleVectorStateKind),
- pattern: keyword
- }));
- }
- }
- }
-
- Promise.all(deferreds).done(function(resps) {
- self._refreshFromServer();
- }, onError);
- }, onError);
- },
-
- // Create a push rule but disabled
- _addDisabledPushRule: function(scope, kind, ruleId, body) {
- const cli = MatrixClientPeg.get();
- return cli.addPushRule(scope, kind, ruleId, body).then(() =>
- cli.setPushRuleEnabled(scope, kind, ruleId, false)
- );
- },
-
- // Check if any legacy im.vector rules need to be ported to the new API
- // for overriding the actions of default rules.
- _portRulesToNewAPI: function(rulesets) {
- const self = this;
- const needsUpdate = [];
- const cli = MatrixClientPeg.get();
-
- for (let kind in rulesets.global) {
- const ruleset = rulesets.global[kind];
- for (let i = 0; i < ruleset.length; ++i) {
- const rule = ruleset[i];
- if (rule.rule_id in LEGACY_RULES) {
- console.log("Porting legacy rule", rule);
- needsUpdate.push( function(kind, rule) {
- return cli.setPushRuleActions(
- 'global', kind, LEGACY_RULES[rule.rule_id], portLegacyActions(rule.actions)
- ).then(() =>
- cli.deletePushRule('global', kind, rule.rule_id)
- ).catch( (e) => {
- console.warn(`Error when porting legacy rule: ${e}`);
- });
- }(kind, rule));
- }
- }
- }
-
- if (needsUpdate.length > 0) {
- // If some of the rules need to be ported then wait for the porting
- // to happen and then fetch the rules again.
- return Promise.all(needsUpdate).then(() =>
- cli.getPushRules()
- );
- } else {
- // Otherwise return the rules that we already have.
- return rulesets;
- }
- },
-
- _refreshFromServer: function() {
- const self = this;
- const pushRulesPromise = MatrixClientPeg.get().getPushRules().then(self._portRulesToNewAPI).then(function(rulesets) {
-
- /// XXX seriously? wtf is this?
- MatrixClientPeg.get().pushRules = rulesets;
-
- // Get homeserver default rules and triage them by categories
- const rule_categories = {
- // The master rule (all notifications disabling)
- '.m.rule.master': 'master',
-
- // The default push rules displayed by Vector UI
- '.m.rule.contains_display_name': 'vector',
- '.m.rule.contains_user_name': 'vector',
- '.m.rule.room_one_to_one': 'vector',
- '.m.rule.message': 'vector',
- '.m.rule.invite_for_me': 'vector',
- //'.m.rule.member_event': 'vector',
- '.m.rule.call': 'vector',
- '.m.rule.suppress_notices': 'vector'
-
- // Others go to others
- };
-
- // HS default rules
- const defaultRules = {master: [], vector: {}, others: []};
-
- for (let kind in rulesets.global) {
- for (let i = 0; i < Object.keys(rulesets.global[kind]).length; ++i) {
- const r = rulesets.global[kind][i];
- const cat = rule_categories[r.rule_id];
- r.kind = kind;
-
- if (r.rule_id[0] === '.') {
- if (cat === 'vector') {
- defaultRules.vector[r.rule_id] = r;
- }
- else if (cat === 'master') {
- defaultRules.master.push(r);
- }
- else {
- defaultRules['others'].push(r);
- }
- }
- }
- }
-
- // Get the master rule if any defined by the hs
- if (defaultRules.master.length > 0) {
- self.state.masterPushRule = defaultRules.master[0];
- }
-
- // parse the keyword rules into our state
- const contentRules = ContentRules.parseContentRules(rulesets);
- self.state.vectorContentRules = {
- vectorState: contentRules.vectorState,
- rules: contentRules.rules,
- };
- self.state.externalContentRules = contentRules.externalRules;
-
- // Build the rules displayed in the Vector UI matrix table
- self.state.vectorPushRules = [];
- self.state.externalPushRules = [];
-
- const vectorRuleIds = [
- '.m.rule.contains_display_name',
- '.m.rule.contains_user_name',
- '_keywords',
- '.m.rule.room_one_to_one',
- '.m.rule.message',
- '.m.rule.invite_for_me',
- //'im.vector.rule.member_event',
- '.m.rule.call',
- '.m.rule.suppress_notices'
- ];
- for (let i in vectorRuleIds) {
- const vectorRuleId = vectorRuleIds[i];
-
- if (vectorRuleId === '_keywords') {
- // keywords needs a special handling
- // For Vector UI, this is a single global push rule but translated in Matrix,
- // it corresponds to all content push rules (stored in self.state.vectorContentRule)
- self.state.vectorPushRules.push({
- "vectorRuleId": "_keywords",
- "description" : (
-
- { _t('Messages containing keywords',
- {},
- { 'span': (sub) =>
- {sub}
- },
- )}
-
- ),
- "vectorState": self.state.vectorContentRules.vectorState
- });
- }
- else {
- const ruleDefinition = VectorPushRulesDefinitions[vectorRuleId];
- const rule = defaultRules.vector[vectorRuleId];
-
- const vectorState = ruleDefinition.ruleToVectorState(rule);
-
- //console.log("Refreshing vectorPushRules for " + vectorRuleId +", "+ ruleDefinition.description +", " + rule +", " + vectorState);
-
- self.state.vectorPushRules.push({
- "vectorRuleId": vectorRuleId,
- "description" : _t(ruleDefinition.description), // Text from VectorPushRulesDefinitions.js
- "rule": rule,
- "vectorState": vectorState,
- });
-
- // if there was a rule which we couldn't parse, add it to the external list
- if (rule && !vectorState) {
- rule.description = ruleDefinition.description;
- self.state.externalPushRules.push(rule);
- }
- }
- }
-
- // Build the rules not managed by Vector UI
- const otherRulesDescriptions = {
- '.m.rule.message': _t('Notify for all other messages/rooms'),
- '.m.rule.fallback': _t('Notify me for anything else'),
- };
-
- for (let i in defaultRules.others) {
- const rule = defaultRules.others[i];
- const ruleDescription = otherRulesDescriptions[rule.rule_id];
-
- // Show enabled default rules that was modified by the user
- if (ruleDescription && rule.enabled && !rule.default) {
- rule.description = ruleDescription;
- self.state.externalPushRules.push(rule);
- }
- }
- });
-
- const pushersPromise = MatrixClientPeg.get().getPushers().then(function(resp) {
- self.setState({pushers: resp.pushers});
- });
-
- Promise.all([pushRulesPromise, pushersPromise]).then(function() {
- self.setState({
- phase: self.phases.DISPLAY
- });
- }, function(error) {
- console.error(error);
- self.setState({
- phase: self.phases.ERROR
- });
- }).finally(() => {
- // actually explicitly update our state having been deep-manipulating it
- self.setState({
- masterPushRule: self.state.masterPushRule,
- vectorContentRules: self.state.vectorContentRules,
- vectorPushRules: self.state.vectorPushRules,
- externalContentRules: self.state.externalContentRules,
- externalPushRules: self.state.externalPushRules,
- });
- }).done();
- },
-
- _updatePushRuleActions: function(rule, actions, enabled) {
- const cli = MatrixClientPeg.get();
-
- return cli.setPushRuleActions(
- 'global', rule.kind, rule.rule_id, actions
- ).then( function() {
- // Then, if requested, enabled or disabled the rule
- if (undefined != enabled) {
- return cli.setPushRuleEnabled(
- 'global', rule.kind, rule.rule_id, enabled
- );
- }
- });
- },
-
- renderNotifRulesTableRow: function(title, className, pushRuleVectorState) {
- return (
-
- );
- }
-
- // When enabled, the master rule inhibits all existing rules
- // So do not show all notification settings
- if (this.state.masterPushRule && this.state.masterPushRule.enabled) {
- return (
-
- {masterPushRuleDiv}
-
-
- { _t('All notifications are currently disabled for all targets.') }.
-
- { _t('Add an email address above to configure email notifications') }
-
;
- } else {
- // This only supports the first email address in your profile for now
- emailNotificationsRow = this.emailNotificationsRow(
- emailThreepids[0].address,
- `${_t('Enable email notifications')} (${emailThreepids[0].address})`
- );
- }
-
- // Build external push rules
- const externalRules = [];
- for (let i in this.state.externalPushRules) {
- const rule = this.state.externalPushRules[i];
- externalRules.push(
{ _t(rule.description) }
);
- }
-
- // Show keywords not displayed by the vector UI as a single external push rule
- let externalKeywords = [];
- for (let i in this.state.externalContentRules) {
- const rule = this.state.externalContentRules[i];
- externalKeywords.push(rule.pattern);
- }
- if (externalKeywords.length) {
- externalKeywords = externalKeywords.join(", ");
- externalRules.push(
{ _t('Notifications on the following keywords follow rules which can’t be displayed here:') } { externalKeywords }
);
- }
-
- let devicesSection;
- if (this.state.pushers === undefined) {
- devicesSection =
{ _t('Unable to fetch notification target list') }
- } else if (this.state.pushers.length == 0) {
- devicesSection = null;
- } else {
- // TODO: It would be great to be able to delete pushers from here too,
- // and this wouldn't be hard to add.
- const rows = [];
- for (let i = 0; i < this.state.pushers.length; ++i) {
- rows.push(
);
- }
-
- let advancedSettings;
- if (externalRules.length) {
- advancedSettings = (
-
-
{ _t('Advanced notification settings') }
- { _t('There are advanced notifications which are not shown here') }.
- { _t('You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply') }.
-