From 324b6e6d4ab21c51d1a02b080336c47b95acc3d8 Mon Sep 17 00:00:00 2001 From: RossyB Date: Fri, 3 May 2019 16:23:45 +0300 Subject: [PATCH 01/33] NY-7339 [WEB] Notification settings - UI --- src/assets/css/fonts.css | 3 ++ src/assets/fonts/demo_font_icons/demo.html | 16 ++++++++ .../fonts/demo_font_icons/fonts/icomoon.eot | Bin 32364 -> 32512 bytes .../fonts/demo_font_icons/fonts/icomoon.svg | 1 + .../fonts/demo_font_icons/fonts/icomoon.ttf | Bin 32200 -> 32348 bytes .../fonts/demo_font_icons/fonts/icomoon.woff | Bin 32276 -> 32424 bytes src/assets/fonts/demo_font_icons/style.css | 3 ++ src/assets/fonts/icons/icomoon.eot | Bin 32364 -> 32512 bytes src/assets/fonts/icons/icomoon.svg | 1 + src/assets/fonts/icons/icomoon.ttf | Bin 32200 -> 32348 bytes src/assets/fonts/icons/icomoon.woff | Bin 32276 -> 32424 bytes .../languages/ActionsMenu/ActionsMenu.en.json | 4 +- src/containers/ActionMenu/ActionMenu.js | 8 +++- src/layouts/Notifications/Notifications.js | 38 ++++++++++++++++++ .../Notifications/Notifications.styles.js | 31 ++++++++++++++ src/layouts/index.js | 6 +-- src/routes.js | 4 +- 17 files changed, 108 insertions(+), 7 deletions(-) mode change 100755 => 100644 src/assets/fonts/icons/icomoon.eot mode change 100755 => 100644 src/assets/fonts/icons/icomoon.svg mode change 100755 => 100644 src/assets/fonts/icons/icomoon.ttf mode change 100755 => 100644 src/assets/fonts/icons/icomoon.woff create mode 100644 src/layouts/Notifications/Notifications.js create mode 100644 src/layouts/Notifications/Notifications.styles.js diff --git a/src/assets/css/fonts.css b/src/assets/css/fonts.css index 2c3793aad..0a1d40821 100644 --- a/src/assets/css/fonts.css +++ b/src/assets/css/fonts.css @@ -327,3 +327,6 @@ .icon-ic_new_chat:before { content: "\e955"; } +.icon-ic_notifications:before { + content: "\e956"; +} diff --git a/src/assets/fonts/demo_font_icons/demo.html b/src/assets/fonts/demo_font_icons/demo.html index e11669474..0e62e313c 100644 --- a/src/assets/fonts/demo_font_icons/demo.html +++ b/src/assets/fonts/demo_font_icons/demo.html @@ -1405,6 +1405,22 @@ +
+
+ + + + icon-ic_notifications +
+
+ + +
+
+ liga: + +
+
diff --git a/src/assets/fonts/demo_font_icons/fonts/icomoon.eot b/src/assets/fonts/demo_font_icons/fonts/icomoon.eot index 661a87351065eee4cc234c1495202d0f01a03d9a..79f4c2a871ad103924e27053023c7c3e4ba49f5b 100644 GIT binary patch delta 403 zcmaF!hq2)wBO60K14B&RL^d;)?C=+E6CKJ0`xqD)_5g80a&BV5tMpfK6Hmz0FH1GE zWME)yU|^`|$w*C15xc7p!oX0)15{_00Tkez!zK&ly8!tr8M!4D)i-5rfcy-go`RhG zL+u0Zxs&4@0cjYEl6fl%B{$pUMnF8c1$jIPdSm^(sK_^U0E9{D)u8zB;B)6Qjs;aacx0EE8 zyN-_GKOIA5Wy8tyD!b(w85rDNglEU|+k9o}OzL*aO4~$+?LIuhL(|Ogte|&$r>F zCIbUw0|P?^Lq=+1ir9WLAiENX8O$<(0-ST$WPtn~K)y;wZb?P?O_@nR{vDv6oSgjR z#LVn=CI*IT51{;x+{B6kh7!hq3=B0uE`vf|Vs7e8FV5dUz5-BvTS0zt2?H}os&)lP zo`IQ#(Q0xEV>e^yrURv-H`~=7Vgvva`bt~? diff --git a/src/assets/fonts/demo_font_icons/fonts/icomoon.svg b/src/assets/fonts/demo_font_icons/fonts/icomoon.svg index 238810aa1..40f18f0ba 100644 --- a/src/assets/fonts/demo_font_icons/fonts/icomoon.svg +++ b/src/assets/fonts/demo_font_icons/fonts/icomoon.svg @@ -93,5 +93,6 @@ + \ No newline at end of file diff --git a/src/assets/fonts/demo_font_icons/fonts/icomoon.ttf b/src/assets/fonts/demo_font_icons/fonts/icomoon.ttf index 44b3bfbf168498a53d1129685168d1bb5f9403c5..0e61c6b0096df98cddd3369cbbc5f7c23d812d9e 100644 GIT binary patch delta 441 zcmX@{oAJ&c#(D-u1_lOhh6V;^1_S?KeItG$_CBD<9w1Ig&P^@=dj5F`7S`d zN=9x;MfFWt8z4UesHY$&KiM&H>Be?828QYzKn1&U6DtZBN*Vt#Fw{%|@)hzDb5mz} zasCGKw*WP?733F}038YhbwEQH6d0IUEGHi5W(=F`!zj&YusMTqYI!{~!zu<|<}hYo z1`Y;Q1|0?lRY4OqWhFLIK~-^4MN@NA6LUL8b2A`qW^5!T%P1x;$0#l)%BZAfYAnLW zv??mVKbmn>*x!&aUS2~LWj$4CX;nRC6+>R${|rhdYm6TaPqH;Zh2t%y1fX`j_0@e%D~M6ay!F~k8fYY z=*dee%^71h->J-G1bS@MWS8pQqAWIUKxt6K#4!G0kN_!VV4A$KR(P{=%~D1HnN)1l delta 280 zcmccfhw;R3#(D-u1_lOhh6V;^1_S?KeItG$_I{wq9w1Ig&P^KOcC2}24q(PF@sqKP=Ip|8&GfM4j^A8 zBe$fY{HDw#ApZ_fPfkvLvSVUqb~_UTL$wD`!H(R-iUNib#(xY9H9#(dLSABS>P#=r z-$1?sP(xcmesKxVp+Hc(0wmAC%wje1KsRIPWFJOpM*Ynhj8n@ecUE@D10}ypofeJf vxB1Gz%>vTEaN}_$$g5y_vO$$OWAx^Xs!YboSF3li1I-4?L~ou|bBGZD?(s@B diff --git a/src/assets/fonts/demo_font_icons/fonts/icomoon.woff b/src/assets/fonts/demo_font_icons/fonts/icomoon.woff index 5795684eba26df4abded0f3fe08ce88b5cfcb1ea..50e984de659ef2f45b996155fe7bf6c349ea8057 100644 GIT binary patch delta 507 zcmbR8hjGPUMzL~#H#Y`G1|XG! zap{T0Ah9DrJ_i&Fq~}zo0maTRFjVw_@Um1h%Z${-6b6Q>2%s7>5Ei?u5Rw5D1d2@n z@>M{Xa}JwqMs7(3P;3iOKgisI>YK7QIr+&zb$&GBe@p+{6l?f|>_Fz5*DR zGXBd;%uQurs0DHv+dz1x7w7MS{NfUze>&jmn1L*27R$*zjNP(fueAUF{r?{*0yO0% z1C+=3|FJlWn8D^Pj8n_&nHg3w@G^%n`vU!^%Amu*pekshrmVy!DyS+hs%UC%YGQ83 zXl@3i&5Vu2WEsW8ZOTOpQg@m{vsv_(wCY3i}%p#>;D{qO7MXEv>4jtYXN^ z`=3F{WR3AdMh5@FLjV5^I$>H`VOI=wb=)N-x#gr)Ri)*)r6jrBb#x5>=@=?28%}ns z?3M?{j@ygy?09~guMFHQV29uM`1Uo30iq{=s5EDc*{o5O$q4l4s>u_ocZ;&vxB+E> X8X003|1d~^lrk`ZB6V|q%~D1HrR086 delta 358 zcmZ4SmvPD;Mv-!VH#Y`G1|X;tVc-VQwI?P|tP`K8EmGf~oSRs{z`&RR6paDlSLv@} z(i4k8Vn={{4k#8#oUik)F#r~nF8Fz{`7shN?Qn8LtN2^3>617WfKW(^rYK?a5@ z79d{*ggNK1$zLeA0S@= zj7u2*wZY+dz1x7w7MS{NfUzFTTLlF#}o5ELM|w7`tUdUupmU`~N>s1Zc`j z1}Km5|6_3$G5yV37^jv`zFOHK50w2bby_r@-{va=H^{jR3^yKEf`bV}Pp+vlXN=yw ir7DwgvSQ6HL7>$@714};7$m@InSdcEyqURnDI)+J$zKit diff --git a/src/assets/fonts/demo_font_icons/style.css b/src/assets/fonts/demo_font_icons/style.css index fd61d8649..5b6ee3ef5 100644 --- a/src/assets/fonts/demo_font_icons/style.css +++ b/src/assets/fonts/demo_font_icons/style.css @@ -285,3 +285,6 @@ .icon-ic_new_chat:before { content: "\e955"; } +.icon-ic_notifications:before { + content: "\e956"; +} diff --git a/src/assets/fonts/icons/icomoon.eot b/src/assets/fonts/icons/icomoon.eot old mode 100755 new mode 100644 index 661a87351065eee4cc234c1495202d0f01a03d9a..79f4c2a871ad103924e27053023c7c3e4ba49f5b GIT binary patch delta 403 zcmaF!hq2)wBO60K14B&RL^d;)?C=+E6CKJ0`xqD)_5g80a&BV5tMpfK6Hmz0FH1GE zWME)yU|^`|$w*C15xc7p!oX0)15{_00Tkez!zK&ly8!tr8M!4D)i-5rfcy-go`RhG zL+u0Zxs&4@0cjYEl6fl%B{$pUMnF8c1$jIPdSm^(sK_^U0E9{D)u8zB;B)6Qjs;aacx0EE8 zyN-_GKOIA5Wy8tyD!b(w85rDNglEU|+k9o}OzL*aO4~$+?LIuhL(|Ogte|&$r>F zCIbUw0|P?^Lq=+1ir9WLAiENX8O$<(0-ST$WPtn~K)y;wZb?P?O_@nR{vDv6oSgjR z#LVn=CI*IT51{;x+{B6kh7!hq3=B0uE`vf|Vs7e8FV5dUz5-BvTS0zt2?H}os&)lP zo`IQ#(Q0xEV>e^yrURv-H`~=7Vgvva`bt~? diff --git a/src/assets/fonts/icons/icomoon.svg b/src/assets/fonts/icons/icomoon.svg old mode 100755 new mode 100644 index 238810aa1..40f18f0ba --- a/src/assets/fonts/icons/icomoon.svg +++ b/src/assets/fonts/icons/icomoon.svg @@ -93,5 +93,6 @@ + \ No newline at end of file diff --git a/src/assets/fonts/icons/icomoon.ttf b/src/assets/fonts/icons/icomoon.ttf old mode 100755 new mode 100644 index 44b3bfbf168498a53d1129685168d1bb5f9403c5..0e61c6b0096df98cddd3369cbbc5f7c23d812d9e GIT binary patch delta 441 zcmX@{oAJ&c#(D-u1_lOhh6V;^1_S?KeItG$_CBD<9w1Ig&P^@=dj5F`7S`d zN=9x;MfFWt8z4UesHY$&KiM&H>Be?828QYzKn1&U6DtZBN*Vt#Fw{%|@)hzDb5mz} zasCGKw*WP?733F}038YhbwEQH6d0IUEGHi5W(=F`!zj&YusMTqYI!{~!zu<|<}hYo z1`Y;Q1|0?lRY4OqWhFLIK~-^4MN@NA6LUL8b2A`qW^5!T%P1x;$0#l)%BZAfYAnLW zv??mVKbmn>*x!&aUS2~LWj$4CX;nRC6+>R${|rhdYm6TaPqH;Zh2t%y1fX`j_0@e%D~M6ay!F~k8fYY z=*dee%^71h->J-G1bS@MWS8pQqAWIUKxt6K#4!G0kN_!VV4A$KR(P{=%~D1HnN)1l delta 280 zcmccfhw;R3#(D-u1_lOhh6V;^1_S?KeItG$_I{wq9w1Ig&P^KOcC2}24q(PF@sqKP=Ip|8&GfM4j^A8 zBe$fY{HDw#ApZ_fPfkvLvSVUqb~_UTL$wD`!H(R-iUNib#(xY9H9#(dLSABS>P#=r z-$1?sP(xcmesKxVp+Hc(0wmAC%wje1KsRIPWFJOpM*Ynhj8n@ecUE@D10}ypofeJf vxB1Gz%>vTEaN}_$$g5y_vO$$OWAx^Xs!YboSF3li1I-4?L~ou|bBGZD?(s@B diff --git a/src/assets/fonts/icons/icomoon.woff b/src/assets/fonts/icons/icomoon.woff old mode 100755 new mode 100644 index 5795684eba26df4abded0f3fe08ce88b5cfcb1ea..50e984de659ef2f45b996155fe7bf6c349ea8057 GIT binary patch delta 507 zcmbR8hjGPUMzL~#H#Y`G1|XG! zap{T0Ah9DrJ_i&Fq~}zo0maTRFjVw_@Um1h%Z${-6b6Q>2%s7>5Ei?u5Rw5D1d2@n z@>M{Xa}JwqMs7(3P;3iOKgisI>YK7QIr+&zb$&GBe@p+{6l?f|>_Fz5*DR zGXBd;%uQurs0DHv+dz1x7w7MS{NfUze>&jmn1L*27R$*zjNP(fueAUF{r?{*0yO0% z1C+=3|FJlWn8D^Pj8n_&nHg3w@G^%n`vU!^%Amu*pekshrmVy!DyS+hs%UC%YGQ83 zXl@3i&5Vu2WEsW8ZOTOpQg@m{vsv_(wCY3i}%p#>;D{qO7MXEv>4jtYXN^ z`=3F{WR3AdMh5@FLjV5^I$>H`VOI=wb=)N-x#gr)Ri)*)r6jrBb#x5>=@=?28%}ns z?3M?{j@ygy?09~guMFHQV29uM`1Uo30iq{=s5EDc*{o5O$q4l4s>u_ocZ;&vxB+E> X8X003|1d~^lrk`ZB6V|q%~D1HrR086 delta 358 zcmZ4SmvPD;Mv-!VH#Y`G1|X;tVc-VQwI?P|tP`K8EmGf~oSRs{z`&RR6paDlSLv@} z(i4k8Vn={{4k#8#oUik)F#r~nF8Fz{`7shN?Qn8LtN2^3>617WfKW(^rYK?a5@ z79d{*ggNK1$zLeA0S@= zj7u2*wZY+dz1x7w7MS{NfUzFTTLlF#}o5ELM|w7`tUdUupmU`~N>s1Zc`j z1}Km5|6_3$G5yV37^jv`zFOHK50w2bby_r@-{va=H^{jR3^yKEf`bV}Pp+vlXN=yw ir7DwgvSQ6HL7>$@714};7$m@InSdcEyqURnDI)+J$zKit diff --git a/src/assets/languages/ActionsMenu/ActionsMenu.en.json b/src/assets/languages/ActionsMenu/ActionsMenu.en.json index f896b1bc1..5341bb22a 100644 --- a/src/assets/languages/ActionsMenu/ActionsMenu.en.json +++ b/src/assets/languages/ActionsMenu/ActionsMenu.en.json @@ -35,5 +35,7 @@ "bots": "Bots", "apps": "Apps", "emailSubject": "Join the NYNJA SuperApp", - "emailBody": "I'm using the new SuperApp called NYNJA! It is an amazing productivity and communications app for teams that work! Download it here: $1 and add me as a contact with my NYNJA user ID: $2" + "emailBody": "I'm using the new SuperApp called NYNJA! It is an amazing productivity and communications app for teams that work! Download it here: $1 and add me as a contact with my NYNJA user ID: $2", + "settings": "Settings", + "notifications": "Notifications" } \ No newline at end of file diff --git a/src/containers/ActionMenu/ActionMenu.js b/src/containers/ActionMenu/ActionMenu.js index 177162838..b8c12f96e 100644 --- a/src/containers/ActionMenu/ActionMenu.js +++ b/src/containers/ActionMenu/ActionMenu.js @@ -34,7 +34,7 @@ class LeftMenu extends React.Component { callsFlag: false, optionsFlag: false }; - + /*getStarredMessages = () => { const { getStarredMessages } = this.props.actions; getStarredMessages(); @@ -104,10 +104,14 @@ class LeftMenu extends React.Component { - + + + + + {/* */} diff --git a/src/layouts/Notifications/Notifications.js b/src/layouts/Notifications/Notifications.js new file mode 100644 index 000000000..1fba948f3 --- /dev/null +++ b/src/layouts/Notifications/Notifications.js @@ -0,0 +1,38 @@ +import React, { PureComponent, Component } from 'react'; +import PropTypes from 'prop-types'; +import { connect } from 'react-redux'; +import { withStyles } from 'material-ui/styles'; +import stylesFunc from './Notifications.styles'; +import Helmet from 'react-helmet'; +import { SliderPanel } from '../../containers'; +import translations from '../../assets/languages/CallHistory/CallHistory.en'; +import LocalizeHOC from "../../containers/LocalizeHOC"; + +const styles = theme => (stylesFunc(theme)); + +export class Notifications extends Component { + constructor(props) { + super(props); + + this.state = { + }; + } + + render() { + const { classes } = this.props; + + return ( +
+ + +
+ ); + } +} + +Notifications.propTypes = { + classes: PropTypes.object.isRequired, +}; + +const localized = LocalizeHOC({ translations })(Notifications); +export default withStyles(styles)(localized); diff --git a/src/layouts/Notifications/Notifications.styles.js b/src/layouts/Notifications/Notifications.styles.js new file mode 100644 index 000000000..c988bca5c --- /dev/null +++ b/src/layouts/Notifications/Notifications.styles.js @@ -0,0 +1,31 @@ +export default theme => ({ + wrap: { + paddingLeft: 285, + transition: 'padding-left 0.2s ease-out', + '& [class*="bottom-panel-wrap"]': { + paddingLeft: 285 + }, + '&.expanded': { + paddingLeft: 80, + '& [class*="bottom-panel-wrap"]': { + paddingLeft: 80 + }, + '& [class*="chat-list-wrap"]': { + width: 80 + }, + '& [class*="first-panel-wrap"]': { + left: 285 + }, + '& [class*="second-panel-wrap"]': { + left: 572 + }, + '& [class*="third-panel-wrap"]': { + left: 858 + }, + '& [class*="hidden-notif"]': { + opacity: 1, + transition: 'opacity 0.2s ease-out 0.2s' + } + } + } +}); diff --git a/src/layouts/index.js b/src/layouts/index.js index c20686497..f98d288dd 100644 --- a/src/layouts/index.js +++ b/src/layouts/index.js @@ -6,10 +6,9 @@ import Groups from './Groups/Groups'; import CallHistory from './CallHistory/CallHistory'; import CreateGroup from './CreateGroup/CreateGroup'; import Contacts from './Contacts/Contacts'; -import { AuthInit } from './Auth'; -import { AuthVerify } from './Auth'; -import { AuthCompletion } from './Auth'; +import { AuthInit, AuthVerify, AuthCompletion } from './Auth'; import Profile from './Profile/Profile'; +import Notifications from './Notifications/Notifications' export { Home, @@ -24,4 +23,5 @@ export { CreateGroup, Contacts, Profile, + Notifications }; diff --git a/src/routes.js b/src/routes.js index 694f0194b..32a544368 100644 --- a/src/routes.js +++ b/src/routes.js @@ -14,7 +14,8 @@ import { Profile, Groups, CallHistory, - CreateGroup + CreateGroup, + Notifications } from './layouts'; import RootMarketplace from './containers/Marketplace/RootMarketplace'; @@ -57,6 +58,7 @@ export default (dispatch) => + {/* */} -- GitLab From b693cee279c1928506d6bf9484d95d9f7d810658 Mon Sep 17 00:00:00 2001 From: RossyB Date: Tue, 7 May 2019 13:55:46 +0300 Subject: [PATCH 02/33] NY-7339 [WEB] Notification settings - UI --- src/assets/languages/Noifications/Notifications.en.json | 3 +++ src/layouts/Notifications/Notifications.js | 7 +++---- 2 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 src/assets/languages/Noifications/Notifications.en.json diff --git a/src/assets/languages/Noifications/Notifications.en.json b/src/assets/languages/Noifications/Notifications.en.json new file mode 100644 index 000000000..e1159493b --- /dev/null +++ b/src/assets/languages/Noifications/Notifications.en.json @@ -0,0 +1,3 @@ +{ + "title": "Notifications | NYNJA" +} \ No newline at end of file diff --git a/src/layouts/Notifications/Notifications.js b/src/layouts/Notifications/Notifications.js index 1fba948f3..c7e799502 100644 --- a/src/layouts/Notifications/Notifications.js +++ b/src/layouts/Notifications/Notifications.js @@ -5,7 +5,7 @@ import { withStyles } from 'material-ui/styles'; import stylesFunc from './Notifications.styles'; import Helmet from 'react-helmet'; import { SliderPanel } from '../../containers'; -import translations from '../../assets/languages/CallHistory/CallHistory.en'; +import translations from '../../assets/languages/Noifications/Notifications.en'; import LocalizeHOC from "../../containers/LocalizeHOC"; const styles = theme => (stylesFunc(theme)); @@ -22,9 +22,8 @@ export class Notifications extends Component { const { classes } = this.props; return ( -
- - +
+
); } -- GitLab From 8d4eddfa9858e11775db91ccf5aa99a0ddb842a9 Mon Sep 17 00:00:00 2001 From: RossyB Date: Tue, 7 May 2019 14:37:54 +0300 Subject: [PATCH 03/33] NY-7339 [WEB] Notification settings - UI --- src/assets/css/fonts.css | 4 +- src/assets/fonts/demo_font_icons/demo.html | 201 +++++++++--------- .../fonts/demo_font_icons/fonts/icomoon.eot | Bin 32512 -> 32696 bytes .../fonts/demo_font_icons/fonts/icomoon.svg | 2 +- .../fonts/demo_font_icons/fonts/icomoon.ttf | Bin 32348 -> 32532 bytes .../fonts/demo_font_icons/fonts/icomoon.woff | Bin 32424 -> 32608 bytes src/assets/fonts/demo_font_icons/style.css | 4 +- src/assets/fonts/icons/icomoon.eot | Bin 32512 -> 32696 bytes src/assets/fonts/icons/icomoon.svg | 2 +- src/assets/fonts/icons/icomoon.ttf | Bin 32348 -> 32532 bytes src/assets/fonts/icons/icomoon.woff | Bin 32424 -> 32608 bytes src/containers/ActionMenu/ActionMenu.js | 2 +- 12 files changed, 109 insertions(+), 106 deletions(-) diff --git a/src/assets/css/fonts.css b/src/assets/css/fonts.css index 0a1d40821..758dec7ee 100644 --- a/src/assets/css/fonts.css +++ b/src/assets/css/fonts.css @@ -327,6 +327,6 @@ .icon-ic_new_chat:before { content: "\e955"; } -.icon-ic_notifications:before { - content: "\e956"; +.icon-ic_notifications_normal:before { + content: "\e957"; } diff --git a/src/assets/fonts/demo_font_icons/demo.html b/src/assets/fonts/demo_font_icons/demo.html index 0e62e313c..cc5227120 100644 --- a/src/assets/fonts/demo_font_icons/demo.html +++ b/src/assets/fonts/demo_font_icons/demo.html @@ -1,22 +1,26 @@ + IcoMoon Demo - + + +
-

Font Name: icomoon (Glyphs: 87)

+

Font Name: icomoon (Glyphs: 87) +

Grid Size: Unknown

- + icon-volume-mute2
@@ -32,7 +36,7 @@
- + icon-add_contact
@@ -48,7 +52,7 @@
- + icon-all
@@ -64,7 +68,7 @@
- + icon-audio
@@ -80,7 +84,7 @@
- + icon-contact_request
@@ -96,7 +100,7 @@
- + icon-contact
@@ -112,7 +116,7 @@
- + icon-files
@@ -128,7 +132,7 @@
- + icon-link
@@ -144,7 +148,7 @@
- + icon-location
@@ -160,7 +164,7 @@
- + icon-photo
@@ -176,7 +180,7 @@
- + icon-photos
@@ -192,7 +196,7 @@
- + icon-storage
@@ -208,7 +212,7 @@
- + icon-upload
@@ -224,7 +228,7 @@
- + icon-video
@@ -240,7 +244,7 @@
- + icon-videocall
@@ -256,7 +260,7 @@
- + icon-voicecall
@@ -272,7 +276,7 @@
- + icon-accepted
@@ -288,7 +292,7 @@
- + icon-ignored
@@ -304,7 +308,7 @@
- + icon-mic
@@ -320,7 +324,7 @@
- + icon-send
@@ -336,7 +340,7 @@
- + icon-calls
@@ -352,7 +356,7 @@
- + icon-chats
@@ -368,7 +372,7 @@
- + icon-contacts
@@ -384,7 +388,7 @@
- + icon-groups
@@ -400,7 +404,7 @@
- + icon-settings
@@ -416,7 +420,7 @@
- + icon-star
@@ -432,7 +436,7 @@
- + icon-add-open
@@ -448,7 +452,7 @@
- + icon-add
@@ -464,7 +468,7 @@
- + icon-play
@@ -480,7 +484,7 @@
- + icon-pause
@@ -496,7 +500,7 @@
- + icon-cancel
@@ -512,7 +516,7 @@
- + icon-download
@@ -528,7 +532,7 @@
- + icon-expand
@@ -544,7 +548,7 @@
- + icon-read
@@ -560,7 +564,7 @@
- + icon-sent
@@ -576,7 +580,7 @@
- + icon-unsent
@@ -592,7 +596,7 @@
- + icon-number
@@ -608,7 +612,7 @@
- + icon-username
@@ -624,7 +628,7 @@
- + icon-country
@@ -640,7 +644,7 @@
- + icon-phone
@@ -656,7 +660,7 @@
- + icon-new-group
@@ -672,7 +676,7 @@
- + icon-channels
@@ -688,7 +692,7 @@
- + icon-family
@@ -704,7 +708,7 @@
- + icon-history
@@ -720,7 +724,7 @@
- + icon-new_channel
@@ -736,7 +740,7 @@
- + icon-new_chat
@@ -752,7 +756,7 @@
- + icon-work
@@ -768,7 +772,7 @@
- + icon-delete
@@ -784,7 +788,7 @@
- + icon-play2
@@ -800,7 +804,7 @@
- + icon-stop
@@ -816,7 +820,7 @@
- + icon-cm_admin
@@ -832,7 +836,7 @@
- + icon-cm_another_transcribe
@@ -848,7 +852,7 @@
- + icon-cm_another_translate
@@ -864,7 +868,7 @@
- + icon-cm_copy
@@ -880,7 +884,7 @@
- + icon-cm_delete
@@ -896,7 +900,7 @@
- + icon-cm_edit
@@ -912,7 +916,7 @@
- + icon-cm_forward
@@ -928,7 +932,7 @@
- + icon-cm_info
@@ -944,7 +948,7 @@
- + icon-cm_reply
@@ -960,7 +964,7 @@
- + icon-cm_share
@@ -976,7 +980,7 @@
- + icon-cm_star
@@ -992,7 +996,7 @@
- + icon-cm_to_downloads
@@ -1008,7 +1012,7 @@
- + icon-cm_to_gallery
@@ -1024,7 +1028,7 @@
- + icon-cm_transcribe
@@ -1040,7 +1044,7 @@
- + icon-cm_translate
@@ -1056,7 +1060,7 @@
- + icon-arrow_down
@@ -1072,7 +1076,7 @@
- + icon-arrow_up
@@ -1088,7 +1092,7 @@
- + icon-calendar
@@ -1104,7 +1108,7 @@
- + icon-schedule
@@ -1120,7 +1124,7 @@
- + icon-save-edited
@@ -1136,7 +1140,7 @@
- + icon-closed-envelope
@@ -1152,7 +1156,7 @@
- + icon-email
@@ -1168,7 +1172,7 @@
- + icon-facebook
@@ -1184,7 +1188,7 @@
- + icon-ic_access
@@ -1200,7 +1204,7 @@
- + icon-ic_app
@@ -1216,7 +1220,7 @@
- + icon-ic_bots
@@ -1232,7 +1236,7 @@
- + icon-ic_design
@@ -1248,7 +1252,7 @@
- + icon-ic_freelance
@@ -1264,7 +1268,7 @@
- + icon-ic_groups
@@ -1280,7 +1284,7 @@
- + icon-ic_interpretation
@@ -1296,7 +1300,7 @@
- + icon-ic_market
@@ -1312,7 +1316,7 @@
- + icon-ic_media
@@ -1328,7 +1332,7 @@
- + icon-ic_stickers
@@ -1344,7 +1348,7 @@
- + icon-ic_support
@@ -1360,7 +1364,7 @@
- + icon-ic_virtual-goods
@@ -1376,7 +1380,7 @@
- + icon-ic_call
@@ -1392,7 +1396,7 @@
- + icon-ic_new_chat
@@ -1407,14 +1411,14 @@
- - + + - icon-ic_notifications + icon-ic_notifications_normal
- - + +
liga: @@ -1427,12 +1431,10 @@

Font Test Drive

- +
 
@@ -1443,4 +1445,5 @@ - + + \ No newline at end of file diff --git a/src/assets/fonts/demo_font_icons/fonts/icomoon.eot b/src/assets/fonts/demo_font_icons/fonts/icomoon.eot index 79f4c2a871ad103924e27053023c7c3e4ba49f5b..2015514674d489f44258ae548340da3a3a24a02d 100644 GIT binary patch delta 638 zcmX|-O>7cT5Xa|r*SAIaC|P!4H;Di>VE{#AativT3yONx81w|uz8RAugdva z1+FDfA7E>aHpta{dHKO<+i%Jxx^SbiT3rK%I&l4m7hRd3aD+Yh@Xx>G6INkq_f!2TVwo)1I;dA0k?`fuUv!P(UFs zF*kLl7w2yve+y7UTS0zt2?H}whM^8<2!jFxGmGWq6vk>p2Oy7!frEjGfrWvQLE&ZC zEA9V(|NjSy0#&_afbtmsKNe>ZGXR>vxLJZ}VtG9?!zu<|<}hYopjK4|9R>zfK@&A) zB{oq(RdG>8Q*%=jb2~px2WB5@$G9614M7`sb0Xy0u*00*`Rhe NGmDMe=6AKH7y+%hc`^V1 diff --git a/src/assets/fonts/demo_font_icons/fonts/icomoon.svg b/src/assets/fonts/demo_font_icons/fonts/icomoon.svg index 40f18f0ba..6eedb812d 100644 --- a/src/assets/fonts/demo_font_icons/fonts/icomoon.svg +++ b/src/assets/fonts/demo_font_icons/fonts/icomoon.svg @@ -93,6 +93,6 @@ - + \ No newline at end of file diff --git a/src/assets/fonts/demo_font_icons/fonts/icomoon.ttf b/src/assets/fonts/demo_font_icons/fonts/icomoon.ttf index 0e61c6b0096df98cddd3369cbbc5f7c23d812d9e..dec4d52080d6e933dab9c3939518c5e6de29ab18 100644 GIT binary patch delta 638 zcmX|-O-vI(6vyAV>ns)8TDQCHZVDM&LaTI3?b2>o8?q)4tUx>v^kUQ%kS1=WNihON z+Y@>)Dq>9hh%p{Kdg;MLjdJj!Mg$W!O`8=BAF=&pg*o11#Uhf|n(G zp$wPEHo%oJWOmUm&D=lc`Gf3W!%BIsGLIL3xIn;+C(=RDOEp!|1nL#jiMSaEaFGF3q1`H( zWZF~O$HZ`0bZxs~F@cjLE0H*GFp;pNAWxa4`lu*0PY9x4wDh4NJ*qNI8L2ylmKv5N zK{ORr!EK7dVM!iNX@*lDQ8cDT$2G<@?!mv=Vz`+fyH~N2$y`T=*K2Ait8#0Cg}lNZ z-YcqXZDsLhq;PKi?HPam7qs&`AO88bddNMv+DI=wAv`w(p0!WaSKO)m@=dj5F`7S`d zN=9x;MfFWt8z4UesHY$&KiM&H>Be?828QYzKn1&U6DtZBN*Vt#Fw{%|@)hzDb5mz} zasCGKw*WP?733F}038YhbwEQH6d0IUEGHhQHgo`Tco;Ysm>5`q{!w@t_DcKz-~a!C zqCiD28K6AI|BuC4#0-E2Fm5hkoLFAZ%&>}qmpP2t7pPU0L5G1sRnSCDS&2<|_j?3)tm1KE8boVu0w)FRB(WvH-cdi;F$%x7o#9nQ5P(-t(XS#lqSp&^{xy zmSOl_ZdUROIq0eMgU4jZKUTN%AcA%T>S2cKF&WGkmsde6KtG#Xstg7n6_)0~cf9%) zOs^TwUAN8_bE{yuejjSu<0|f4$rTqs+knQKj0Zyha&a=0%)$_cuJFE|!>Y}0&FG1lEiLYrR6EG|{dP2#3Wy$}YpN~~kC=)@ zZNHxjj%g|x*67ih(6IVCMJxK zMs;<1y29_;0p2(9RsYS9TH!)9vg MXEINk->M(+U+8#}bpQYW delta 491 zcmaFxk8#CcMv-!VH#Y`G1|XDPp`x_F*%WJ5j ztfwk1t*WQ2V#v$;pFzoFjqyW92LHlB|Njg+VOm;YR}6J^+$ANs<)l?rrRBJ#B)Qym zbPWIL7%D3pPVTDelW}_yo*mC`^Ob>{1?=)0AK$(PF+lWYlj;SGEI{#9lW)}QW@fQ* K+dQrI6e9rE<9gHp diff --git a/src/assets/fonts/demo_font_icons/style.css b/src/assets/fonts/demo_font_icons/style.css index 5b6ee3ef5..7e1a763b2 100644 --- a/src/assets/fonts/demo_font_icons/style.css +++ b/src/assets/fonts/demo_font_icons/style.css @@ -285,6 +285,6 @@ .icon-ic_new_chat:before { content: "\e955"; } -.icon-ic_notifications:before { - content: "\e956"; +.icon-ic_notifications_normal:before { + content: "\e957"; } diff --git a/src/assets/fonts/icons/icomoon.eot b/src/assets/fonts/icons/icomoon.eot index 79f4c2a871ad103924e27053023c7c3e4ba49f5b..2015514674d489f44258ae548340da3a3a24a02d 100644 GIT binary patch delta 638 zcmX|-O>7cT5Xa|r*SAIaC|P!4H;Di>VE{#AativT3yONx81w|uz8RAugdva z1+FDfA7E>aHpta{dHKO<+i%Jxx^SbiT3rK%I&l4m7hRd3aD+Yh@Xx>G6INkq_f!2TVwo)1I;dA0k?`fuUv!P(UFs zF*kLl7w2yve+y7UTS0zt2?H}whM^8<2!jFxGmGWq6vk>p2Oy7!frEjGfrWvQLE&ZC zEA9V(|NjSy0#&_afbtmsKNe>ZGXR>vxLJZ}VtG9?!zu<|<}hYopjK4|9R>zfK@&A) zB{oq(RdG>8Q*%=jb2~px2WB5@$G9614M7`sb0Xy0u*00*`Rhe NGmDMe=6AKH7y+%hc`^V1 diff --git a/src/assets/fonts/icons/icomoon.svg b/src/assets/fonts/icons/icomoon.svg index 40f18f0ba..6eedb812d 100644 --- a/src/assets/fonts/icons/icomoon.svg +++ b/src/assets/fonts/icons/icomoon.svg @@ -93,6 +93,6 @@ - + \ No newline at end of file diff --git a/src/assets/fonts/icons/icomoon.ttf b/src/assets/fonts/icons/icomoon.ttf index 0e61c6b0096df98cddd3369cbbc5f7c23d812d9e..dec4d52080d6e933dab9c3939518c5e6de29ab18 100644 GIT binary patch delta 638 zcmX|-O-vI(6vyAV>ns)8TDQCHZVDM&LaTI3?b2>o8?q)4tUx>v^kUQ%kS1=WNihON z+Y@>)Dq>9hh%p{Kdg;MLjdJj!Mg$W!O`8=BAF=&pg*o11#Uhf|n(G zp$wPEHo%oJWOmUm&D=lc`Gf3W!%BIsGLIL3xIn;+C(=RDOEp!|1nL#jiMSaEaFGF3q1`H( zWZF~O$HZ`0bZxs~F@cjLE0H*GFp;pNAWxa4`lu*0PY9x4wDh4NJ*qNI8L2ylmKv5N zK{ORr!EK7dVM!iNX@*lDQ8cDT$2G<@?!mv=Vz`+fyH~N2$y`T=*K2Ait8#0Cg}lNZ z-YcqXZDsLhq;PKi?HPam7qs&`AO88bddNMv+DI=wAv`w(p0!WaSKO)m@=dj5F`7S`d zN=9x;MfFWt8z4UesHY$&KiM&H>Be?828QYzKn1&U6DtZBN*Vt#Fw{%|@)hzDb5mz} zasCGKw*WP?733F}038YhbwEQH6d0IUEGHhQHgo`Tco;Ysm>5`q{!w@t_DcKz-~a!C zqCiD28K6AI|BuC4#0-E2Fm5hkoLFAZ%&>}qmpP2t7pPU0L5G1sRnSCDS&2<|_j?3)tm1KE8boVu0w)FRB(WvH-cdi;F$%x7o#9nQ5P(-t(XS#lqSp&^{xy zmSOl_ZdUROIq0eMgU4jZKUTN%AcA%T>S2cKF&WGkmsde6KtG#Xstg7n6_)0~cf9%) zOs^TwUAN8_bE{yuejjSu<0|f4$rTqs+knQKj0Zyha&a=0%)$_cuJFE|!>Y}0&FG1lEiLYrR6EG|{dP2#3Wy$}YpN~~kC=)@ zZNHxjj%g|x*67ih(6IVCMJxK zMs;<1y29_;0p2(9RsYS9TH!)9vg MXEINk->M(+U+8#}bpQYW delta 491 zcmaFxk8#CcMv-!VH#Y`G1|XDPp`x_F*%WJ5j ztfwk1t*WQ2V#v$;pFzoFjqyW92LHlB|Njg+VOm;YR}6J^+$ANs<)l?rrRBJ#B)Qym zbPWIL7%D3pPVTDelW}_yo*mC`^Ob>{1?=)0AK$(PF+lWYlj;SGEI{#9lW)}QW@fQ* K+dQrI6e9rE<9gHp diff --git a/src/containers/ActionMenu/ActionMenu.js b/src/containers/ActionMenu/ActionMenu.js index b8c12f96e..fb523442c 100644 --- a/src/containers/ActionMenu/ActionMenu.js +++ b/src/containers/ActionMenu/ActionMenu.js @@ -109,7 +109,7 @@ class LeftMenu extends React.Component { - + {/* */} -- GitLab From abd7c1fa8bc4fb22c0a0f15b2a96e35aba0a54ca Mon Sep 17 00:00:00 2001 From: RossyB Date: Tue, 7 May 2019 19:56:53 +0300 Subject: [PATCH 04/33] NY-7339 [WEB] Notification settings - UI --- .../Noifications/Notifications.en.json | 14 +- src/layouts/Notifications/Notifications.js | 125 +++++++++++++++++- .../Notifications/Notifications.styles.js | 109 ++++++++++++--- 3 files changed, 225 insertions(+), 23 deletions(-) diff --git a/src/assets/languages/Noifications/Notifications.en.json b/src/assets/languages/Noifications/Notifications.en.json index e1159493b..6353bc410 100644 --- a/src/assets/languages/Noifications/Notifications.en.json +++ b/src/assets/languages/Noifications/Notifications.en.json @@ -1,3 +1,15 @@ { - "title": "Notifications | NYNJA" + "title": "Notifications | NYNJA", + "appSounds": "App Sounds", + "messageNotifications": "Message Notifications", + "showNotifications": "Show Notifications", + "incomingMessageSound": "Incoming message sound", + "groupEvents": "Group Events", + "groupEventSound": "Group event sound", + "callNotifications": "Call Notifications", + "soundNotificationsDuringCall": "Sound notifications durring call", + "incomingCallSoundInMutedChat": "Incoming call sound In muted chat", + "incomingCallSound": "Incoming call sound", + "otherNotifications": "Other Notifications", + "otherNotificationsSound": "Other notifications sound" } \ No newline at end of file diff --git a/src/layouts/Notifications/Notifications.js b/src/layouts/Notifications/Notifications.js index c7e799502..e6075ee27 100644 --- a/src/layouts/Notifications/Notifications.js +++ b/src/layouts/Notifications/Notifications.js @@ -2,6 +2,7 @@ import React, { PureComponent, Component } from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { withStyles } from 'material-ui/styles'; +import { Switch } from 'material-ui' import stylesFunc from './Notifications.styles'; import Helmet from 'react-helmet'; import { SliderPanel } from '../../containers'; @@ -15,15 +16,135 @@ export class Notifications extends Component { super(props); this.state = { + showSoundsPanel: false, }; } + toggle(panelName) { + this.setState({ [`${panelName}`]: !this.state[panelName] }); + } + + handleNotificationsChange = () => { + + } + render() { - const { classes } = this.props; + const { classes, translate } = this.props; + const { showSoundsPanel } = this.state; return (
- + +
+
+
+ {translate('appSounds')} + +
+
+ {/* Message notifications */} +
+

{translate('messageNotifications')}

+
+
+ {translate('showNotifications')} + +
+
+ +
+ {/* Group events */} +
+

{translate('groupEvents')}

+
+
+ {translate('showNotifications')} + +
+
+ +
+ {/* Call Notifications */} +
+

{translate('callNotifications')}

+
+
+ +
+
+ {translate('incomingCallSoundInMutedChat')} + +
+
+ +
+ {/* Other Notifications */} +
+

{translate('otherNotifications')}

+
+
+ {translate('showNotifications')} + +
+
+ +
+
); } diff --git a/src/layouts/Notifications/Notifications.styles.js b/src/layouts/Notifications/Notifications.styles.js index c988bca5c..8e3290d06 100644 --- a/src/layouts/Notifications/Notifications.styles.js +++ b/src/layouts/Notifications/Notifications.styles.js @@ -1,3 +1,5 @@ +import { BorderBottom } from "material-ui-icons"; + export default theme => ({ wrap: { paddingLeft: 285, @@ -5,27 +7,94 @@ export default theme => ({ '& [class*="bottom-panel-wrap"]': { paddingLeft: 285 }, - '&.expanded': { - paddingLeft: 80, - '& [class*="bottom-panel-wrap"]': { - paddingLeft: 80 + }, + notificationWrap: { + position: 'fixed', + top: 64, + left: 205, + zIndex: 9, + width: 572, + height: 'calc(100% - 64px)', + background: '#27292e', + transition: 'width 0.2s ease-out' + }, + settingsItemWrap: { + marginTop: '20px', + borderBottom: '1px solid #34373c', + borderTop: '1px solid #34373c' + }, + toogleItem: { + width: '100%', + color: '#ffffff', + height: 36, + display: 'flex', + padding: '2px 10px 1px', + position: 'relative', + alignItems: 'center', + lineHeight: 1.2, + flexDirection: 'row', + justifyContent: 'space-between', + + }, + toggleLabel: { + overflowWrap: 'break-word', + marginLeft: 25, + fontSize: '16px' + }, + switchChecked: { + color: '#C90010 !important' + }, + separator: { + width: '100%', + color: '#919294', + height: 36, + display: 'flex', + padding: '9px 35px', + position: 'relative', + lineHeight: 1.2, + flexDirection: 'row', + justifyContent: 'space-between', + background: "#1b1c20", + marginTop: '20px', + }, + buttonContainer: { + '& button': { + textTransform: 'capitalize', + fontSize: '1em', + flexDirection: 'column', + alignItems: 'flex-start', + width: '100%', + color: '#FFFFFF', + padding: 10, + paddingLeft: 35, + textAlign: 'left', + cursor: 'pointer', + transition: 'background 0.2s ease-out', + '&:hover': { + background: '#151619', + '&:after': { + borderColor: '#d00000' + } }, - '& [class*="chat-list-wrap"]': { - width: 80 - }, - '& [class*="first-panel-wrap"]': { - left: 285 - }, - '& [class*="second-panel-wrap"]': { - left: 572 - }, - '& [class*="third-panel-wrap"]': { - left: 858 - }, - '& [class*="hidden-notif"]': { - opacity: 1, - transition: 'opacity 0.2s ease-out 0.2s' + '&:disabled': { + color: 'graytext' + } + } + }, + iconWrapp: { + position: 'realative', + borderTop: '1px solid #34373c', + borderBottom: '1px solid #34373c', + '& i.icon-expand': { + transform: 'rotate(-90deg)', + position: 'absolute', + right: '20px', + lineHeight: '18px', + color: '#34373c', + '&:before': { + fontSize: 8 } } - } + }, + }); -- GitLab From 5907347b4285f6a5e0459ea0d482546d97e33d8f Mon Sep 17 00:00:00 2001 From: RossyB Date: Wed, 8 May 2019 11:50:12 +0300 Subject: [PATCH 05/33] NY-7339 [WEB] Notification settings - UI --- src/layouts/Notifications/Notifications.js | 56 +++++++++++++++------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/src/layouts/Notifications/Notifications.js b/src/layouts/Notifications/Notifications.js index e6075ee27..961d872d9 100644 --- a/src/layouts/Notifications/Notifications.js +++ b/src/layouts/Notifications/Notifications.js @@ -16,12 +16,31 @@ export class Notifications extends Component { super(props); this.state = { - showSoundsPanel: false, + panelsStatuses: { + showIncomingMessageSoundsPanel: false, + showGroupEventSoundsPanel: false, + showIncomingCallSoundsPanel: false, + showOtherNotificationsSoundsPanel: false, + showMuteUnmuteSoundPanel: false + }, + }; } toggle(panelName) { - this.setState({ [`${panelName}`]: !this.state[panelName] }); + const newStatuses = Object.assign({}, this.state.panelsStatuses); + + for (let panel in newStatuses) { + if (newStatuses.hasOwnProperty(panel)) { + if (panel === panelName) { + newStatuses[panel] = !newStatuses[panel]; + } else { + newStatuses[panel] = false; + } + } + } + + this.setState({ panelsStatuses: newStatuses }); } handleNotificationsChange = () => { @@ -30,7 +49,8 @@ export class Notifications extends Component { render() { const { classes, translate } = this.props; - const { showSoundsPanel } = this.state; + const { showIncomingMessageSoundsPanel, showGroupEventSoundsPanel, showIncomingCallSoundsPanel, + showOtherNotificationsSoundsPanel, showMuteUnmuteSoundPanel } = this.state.panelsStatuses; return (
@@ -63,10 +83,10 @@ export class Notifications extends Component {
{/* Group events */} @@ -85,10 +105,10 @@ export class Notifications extends Component {
{/* Call Notifications */} @@ -98,10 +118,10 @@ export class Notifications extends Component {
@@ -116,10 +136,10 @@ export class Notifications extends Component {
{/* Other Notifications */} @@ -138,10 +158,10 @@ export class Notifications extends Component {
-- GitLab From df977771fb7645a030ce0dfd621f8b5bb47853b6 Mon Sep 17 00:00:00 2001 From: RossyB Date: Wed, 8 May 2019 14:43:19 +0300 Subject: [PATCH 06/33] NY-7339 [WEB] Notification settings - UI --- .../Noifications/Notifications.en.json | 7 +- src/layouts/Notifications/Notifications.js | 66 +++++++++++++------ .../Notifications/Notifications.styles.js | 17 ++++- 3 files changed, 64 insertions(+), 26 deletions(-) diff --git a/src/assets/languages/Noifications/Notifications.en.json b/src/assets/languages/Noifications/Notifications.en.json index 6353bc410..cd1980e58 100644 --- a/src/assets/languages/Noifications/Notifications.en.json +++ b/src/assets/languages/Noifications/Notifications.en.json @@ -7,9 +7,12 @@ "groupEvents": "Group Events", "groupEventSound": "Group event sound", "callNotifications": "Call Notifications", - "soundNotificationsDuringCall": "Sound notifications durring call", + "soundNotificationsDuringCall": "Sound notifications during call", "incomingCallSoundInMutedChat": "Incoming call sound In muted chat", "incomingCallSound": "Incoming call sound", "otherNotifications": "Other Notifications", - "otherNotificationsSound": "Other notifications sound" + "otherNotificationsSound": "Other notifications sound", + "notifications": "Notifications", + "mute": "Mute", + "unmute": "Unmute" } \ No newline at end of file diff --git a/src/layouts/Notifications/Notifications.js b/src/layouts/Notifications/Notifications.js index 961d872d9..867eaea4e 100644 --- a/src/layouts/Notifications/Notifications.js +++ b/src/layouts/Notifications/Notifications.js @@ -16,12 +16,19 @@ export class Notifications extends Component { super(props); this.state = { + allAppSound: true, + allMessageNotifications: true, + allGroupEventsNotifications: true, + allIncomingCallNotifications: true, + allOthernotifications: true, + muteUnmuteDuringCallNotifications: true, panelsStatuses: { showIncomingMessageSoundsPanel: false, showGroupEventSoundsPanel: false, showIncomingCallSoundsPanel: false, showOtherNotificationsSoundsPanel: false, - showMuteUnmuteSoundPanel: false + showMuteUnmuteDuringCallSoundPanel: false, + showNotificationsPanel: false }, }; @@ -43,14 +50,15 @@ export class Notifications extends Component { this.setState({ panelsStatuses: newStatuses }); } - handleNotificationsChange = () => { + handleNotificationsChange = (notifications) => { } render() { const { classes, translate } = this.props; + const { notifications, allAppSound, allMessageNotifications, allGroupEventsNotifications, allIncomingCallNotifications, allOthernotifications } = this.state; const { showIncomingMessageSoundsPanel, showGroupEventSoundsPanel, showIncomingCallSoundsPanel, - showOtherNotificationsSoundsPanel, showMuteUnmuteSoundPanel } = this.state.panelsStatuses; + showOtherNotificationsSoundsPanel, showMuteUnmuteDuringCallSoundPanel, showNotificationsPanel } = this.state.panelsStatuses; return (
@@ -60,10 +68,10 @@ export class Notifications extends Component {
{translate('appSounds')}
@@ -74,10 +82,10 @@ export class Notifications extends Component {
{translate('showNotifications')}
@@ -96,10 +104,10 @@ export class Notifications extends Component {
{translate('showNotifications')}
@@ -118,19 +126,22 @@ export class Notifications extends Component {
{translate('incomingCallSoundInMutedChat')}
@@ -149,10 +160,10 @@ export class Notifications extends Component {
{translate('showNotifications')}
@@ -165,6 +176,19 @@ export class Notifications extends Component {
+ + {/* Notifications Panel */} + +
+ {translate('notifications')} + +
+
); } diff --git a/src/layouts/Notifications/Notifications.styles.js b/src/layouts/Notifications/Notifications.styles.js index 8e3290d06..297e90e8f 100644 --- a/src/layouts/Notifications/Notifications.styles.js +++ b/src/layouts/Notifications/Notifications.styles.js @@ -1,5 +1,3 @@ -import { BorderBottom } from "material-ui-icons"; - export default theme => ({ wrap: { paddingLeft: 285, @@ -94,7 +92,20 @@ export default theme => ({ '&:before': { fontSize: 8 } + }, + '& .members-number': { + position: 'absolute', + lineHeight: '18px', + right: '40px', + color: '#4c4e52', + fontSize: 14 } }, - + notificationsPanel: { + left: 777, + zIndex: 7, + background: '#151619', + top: 66, + paddingTop: 20 + }, }); -- GitLab From 4ae8c4b8bccbacbecd1dfb8460498e9fe40bab65 Mon Sep 17 00:00:00 2001 From: RossyB Date: Wed, 8 May 2019 14:50:06 +0300 Subject: [PATCH 07/33] NY-7339 [WEB] Notification settings - UI --- src/layouts/Notifications/Notifications.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/layouts/Notifications/Notifications.js b/src/layouts/Notifications/Notifications.js index 867eaea4e..861ed2d1c 100644 --- a/src/layouts/Notifications/Notifications.js +++ b/src/layouts/Notifications/Notifications.js @@ -56,7 +56,8 @@ export class Notifications extends Component { render() { const { classes, translate } = this.props; - const { notifications, allAppSound, allMessageNotifications, allGroupEventsNotifications, allIncomingCallNotifications, allOthernotifications } = this.state; + const { notifications, allAppSound, allMessageNotifications, allGroupEventsNotifications, + allIncomingCallNotifications, allOthernotifications, muteUnmuteDuringCallNotifications } = this.state; const { showIncomingMessageSoundsPanel, showGroupEventSoundsPanel, showIncomingCallSoundsPanel, showOtherNotificationsSoundsPanel, showMuteUnmuteDuringCallSoundPanel, showNotificationsPanel } = this.state.panelsStatuses; -- GitLab From 5d6635f187454ecb8518aeab6363fa076e83e836 Mon Sep 17 00:00:00 2001 From: RossyB Date: Wed, 8 May 2019 16:27:08 +0300 Subject: [PATCH 08/33] NY-7339 [WEB] Notification settings - UI --- src/layouts/Notifications/Notifications.js | 15 +++++++++++---- src/layouts/Notifications/Notifications.styles.js | 7 +++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/layouts/Notifications/Notifications.js b/src/layouts/Notifications/Notifications.js index 861ed2d1c..a2f9b8154 100644 --- a/src/layouts/Notifications/Notifications.js +++ b/src/layouts/Notifications/Notifications.js @@ -28,7 +28,6 @@ export class Notifications extends Component { showIncomingCallSoundsPanel: false, showOtherNotificationsSoundsPanel: false, showMuteUnmuteDuringCallSoundPanel: false, - showNotificationsPanel: false }, }; @@ -56,10 +55,10 @@ export class Notifications extends Component { render() { const { classes, translate } = this.props; - const { notifications, allAppSound, allMessageNotifications, allGroupEventsNotifications, - allIncomingCallNotifications, allOthernotifications, muteUnmuteDuringCallNotifications } = this.state; + const { allAppSound, allMessageNotifications, allGroupEventsNotifications, allIncomingCallNotifications, + allOthernotifications, muteUnmuteDuringCallNotifications } = this.state; const { showIncomingMessageSoundsPanel, showGroupEventSoundsPanel, showIncomingCallSoundsPanel, - showOtherNotificationsSoundsPanel, showMuteUnmuteDuringCallSoundPanel, showNotificationsPanel } = this.state.panelsStatuses; + showOtherNotificationsSoundsPanel, showMuteUnmuteDuringCallSoundPanel } = this.state.panelsStatuses; return (
@@ -190,6 +189,14 @@ export class Notifications extends Component { />
+ {/* Sound Panel */} + +
+ {translate('notifications')} +
+
); } diff --git a/src/layouts/Notifications/Notifications.styles.js b/src/layouts/Notifications/Notifications.styles.js index 297e90e8f..421e6cbd0 100644 --- a/src/layouts/Notifications/Notifications.styles.js +++ b/src/layouts/Notifications/Notifications.styles.js @@ -108,4 +108,11 @@ export default theme => ({ top: 66, paddingTop: 20 }, + soundsPanel: { + left: 777, + zIndex: 7, + background: '#151619', + top: 66, + paddingTop: 20 + }, }); -- GitLab From 5a2a5946f12c2746e2e864acb69456981133bc10 Mon Sep 17 00:00:00 2001 From: JelianRadoev Date: Wed, 8 May 2019 17:35:55 +0300 Subject: [PATCH 09/33] NY-7369 [WEB] Notifications settings - modules, sagas init --- src/core/resource/Root.reducer.js | 4 +- src/core/resource/Root.saga.js | 2 + .../profile/sagas/ProfileInit.saga.js | 26 +++--- src/core/resource/settings/index.js | 9 +++ .../settings/modules/Settings.module.js | 81 +++++++++++++++++++ .../settings/sagas/RootSettings.saga.js | 10 +++ .../resource/settings/sagas/Settings.saga.js | 13 +++ 7 files changed, 131 insertions(+), 14 deletions(-) create mode 100644 src/core/resource/settings/index.js create mode 100644 src/core/resource/settings/modules/Settings.module.js create mode 100644 src/core/resource/settings/sagas/RootSettings.saga.js create mode 100644 src/core/resource/settings/sagas/Settings.saga.js diff --git a/src/core/resource/Root.reducer.js b/src/core/resource/Root.reducer.js index 8e7ea181d..da6513cf7 100644 --- a/src/core/resource/Root.reducer.js +++ b/src/core/resource/Root.reducer.js @@ -26,6 +26,7 @@ import { settingsReducer } from './messages/settings/index'; import { scheduleMessageReducer } from './messages/schedule'; import { marketplaceReducer } from './marketplace'; import { storageReducer } from './storage'; +import { settings } from './settings/index'; // avoid circle dependencies const appReducer = combineReducers({ @@ -59,7 +60,8 @@ const appReducer = combineReducers({ room }), marketplace: marketplaceReducer, - storage: storageReducer + storage: storageReducer, + settings, }); const rootReducer = (state, action) => { diff --git a/src/core/resource/Root.saga.js b/src/core/resource/Root.saga.js index 80aeea0a3..dce5270e3 100644 --- a/src/core/resource/Root.saga.js +++ b/src/core/resource/Root.saga.js @@ -18,6 +18,7 @@ import { rootSettings } from './messages/settings/index'; import { rootScheduleMessage } from './messages/schedule/'; import rootMarketplaceSaga from './marketplace/modules/MarketplaceSaga'; import { rootStorageSaga } from './storage'; +import { rootSettingsSaga } from './settings/index'; const isGenerator = fn => fn instanceof (function* () {}).constructor; @@ -41,6 +42,7 @@ function * rootSaga() { yield fork(rootScheduleMessage); yield fork(rootMarketplaceSaga); yield fork(rootStorageSaga); + yield fork(rootSettingsSaga); } export { rootSaga }; diff --git a/src/core/resource/profile/sagas/ProfileInit.saga.js b/src/core/resource/profile/sagas/ProfileInit.saga.js index 3c501c348..e7b4cae7d 100644 --- a/src/core/resource/profile/sagas/ProfileInit.saga.js +++ b/src/core/resource/profile/sagas/ProfileInit.saga.js @@ -3,31 +3,29 @@ import { browserHistory } from 'react-router'; import { profileInitActions as actions, profileInitSelectors as selectors, - profileSelectors } from '../index'; -import { browserStorage } from 'Core/store'; import { userListActions, userListSelectors } from '../../userlist'; import { roomListActions, roomListSelectors } from '../../roomlist'; import { contactsActions, contactsSelectors } from '../../contacts'; import { rosterInitActions, rosterInitSelectors } from '../../roster'; -import { p2pActions, p2pSelectors, p2pFilters, p2pMembersSelectors } from '../../messages/personal'; -import { historyActions } from '../../messages/history'; +import { settingsActions, settingsSelectors } from '../../settings'; +import { p2pActions, p2pSelectors } from '../../messages/personal'; import { credentialsSelectors, manageCredentialsActions as credentialsActions } from "../../credentials"; import constants from 'Core/configs/Constants.config'; -function * profileInit() { +function* profileInit() { //add works only when auth`ed, not blacklisted //change true to configurable attempts - while(true) { + while (true) { const { payload } = yield take(actions.init.getType()); const profile = selectors.pullReceivedProfile(payload); yield put(actions.initSuccess(profile)); yield put(rosterInitActions.init(rosterInitSelectors.pullReceivedRosters(payload))); yield put(contactsActions.init(contactsSelectors.pullReceivedContacts(payload))); - + const roomList = yield call(roomListSelectors.pullReceivedRoomList, payload); yield put(roomListActions.init(roomList)); const userList = yield call(userListSelectors.pullReceivedUserList, payload); @@ -35,10 +33,13 @@ function * profileInit() { yield put(p2pActions.init(p2pSelectors.pullReceivedUnread(payload))); + const settings = yield call(settingsSelectors.pullReceivedSettingsList, payload); + yield put(settingsActions.init(settings)); + const instance = yield select(credentialsSelectors.getStatus); const user = yield select(userListSelectors.getUserById, profile.phone_id); if (user && Object.keys(user).length && user.names) { - if(window.Intercom){ + if (window.Intercom) { window.Intercom('boot', { app_id: constants.intercomAppId, alignment: constants.intercomAlignment, @@ -46,22 +47,21 @@ function * profileInit() { horizontal_padding: constants.horizontal_padding, user_id: user.phone_id, phone: String(user.phone_id).split("_").pop(), - name: user.names+" "+user.surnames, - }); + name: user.names + " " + user.surnames, + }); } const status = { is_authorized: !instance.is_authorized }; yield put(credentialsActions.update(status)); const path = window.location.pathname; - if (path === "/" || path.search(/^\/auth.+/g) > -1 ) { + if (path === "/" || path.search(/^\/auth.+/g) > -1) { yield call(browserHistory.push, "/dashboard"); } - } else { yield call(browserHistory.push, "/auth/completion"); } } } -export { profileInit }; \ No newline at end of file +export { profileInit }; diff --git a/src/core/resource/settings/index.js b/src/core/resource/settings/index.js new file mode 100644 index 000000000..51ad64d23 --- /dev/null +++ b/src/core/resource/settings/index.js @@ -0,0 +1,9 @@ +import { settingsActions, settingsSelectors, settings } from './modules/Settings.module'; +import rootSettingsSaga from './sagas/RootSettings.saga'; + +export { + settingsActions, + settingsSelectors, + settings, + rootSettingsSaga +}; diff --git a/src/core/resource/settings/modules/Settings.module.js b/src/core/resource/settings/modules/Settings.module.js new file mode 100644 index 000000000..c18e6edbc --- /dev/null +++ b/src/core/resource/settings/modules/Settings.module.js @@ -0,0 +1,81 @@ +import { createAction, createReducer } from 'redux-act'; +import merge from 'deepmerge'; + +const stateName = 'settings'; +const notifiactionsName = 'notifications'; +const actionPrefix = stateName.toUpperCase(); +const notificationsPrefix = notifiactionsName.toUpperCase(); +const initialState = {}; + +const initApply = data => data; + +// Selectors START +const getInstance = (state) => { + const instance = state[stateName] || {}; + if (instance.hasOwnProperty('init') && !instance.init) { + throw new Error(`${stateName}, have not already init'ed`); + } + return instance; +}; + +const pullReceivedSettingsList = ({ settings = [] }) => { + const data = {}; + + Object.assign(data, { + init: true, + updated: (new Date()).getTime(), + notifications: {} + }); + + return data; +}; + +const getNotificationsSettings = (state) => { + const settings = getInstance(state); + return settings[notifiactionsName] || {}; +}; +// Selectors END + +// Actions START +const init = createAction(`${actionPrefix}_INIT`, initApply); +const updateNotificationsSettings = createAction(`${actionPrefix}_${notificationsPrefix}_UPDATE`, initApply); +// Actions END + +// Handlers START +const defaultMergeHandler = (state, payload) => merge(state, payload); + +const updateNotificationsSettingsHandler = (state, payload) => { + return Object.assign({}, state, + merge(state, { + [notifiactionsName]: { + [payload.setting]: payload.value + } + }), + { + init: true, + updated: (new Date()).getTime() + }); +}; +// Handlers END + +const settings = createReducer({ + [init]: defaultMergeHandler, + [updateNotificationsSettings]: updateNotificationsSettingsHandler, +}, initialState); + +const settingsActions = { + init, + updateNotificationsSettings, +}; + +const settingsSelectors = { + getInstance, + pullReceivedSettingsList, + getNotificationsSettings, +}; + +export { + settingsActions, + settingsSelectors, + settings, +}; diff --git a/src/core/resource/settings/sagas/RootSettings.saga.js b/src/core/resource/settings/sagas/RootSettings.saga.js new file mode 100644 index 000000000..d31aa758e --- /dev/null +++ b/src/core/resource/settings/sagas/RootSettings.saga.js @@ -0,0 +1,10 @@ +import { fork } from 'redux-saga/effects'; +import { + updateNotificationsSettingsWatcher, +} from './Settings.saga'; + +function* rootSettingsSaga() { + yield fork(updateNotificationsSettingsWatcher); +} + +export default rootSettingsSaga; diff --git a/src/core/resource/settings/sagas/Settings.saga.js b/src/core/resource/settings/sagas/Settings.saga.js new file mode 100644 index 000000000..e730f1938 --- /dev/null +++ b/src/core/resource/settings/sagas/Settings.saga.js @@ -0,0 +1,13 @@ +import { take, takeEvery, call, put, select } from 'redux-saga/effects'; + +function* updateNotificationsSettings() { + // TODO +} + +function* updateNotificationsSettingsWatcher() { + // TODO +} + +export { + updateNotificationsSettingsWatcher, +}; -- GitLab From ff40491b215cca5175747f92db7d10203874ddcf Mon Sep 17 00:00:00 2001 From: JelianRadoev Date: Thu, 9 May 2019 16:40:37 +0300 Subject: [PATCH 10/33] NY-7369 [WEB] Notifications settings - save settings to store and localStorage --- .../settings/modules/Settings.module.js | 61 +++++++++++--- .../resource/settings/sagas/Settings.saga.js | 13 ++- src/layouts/Notifications/Notifications.js | 84 ++++++++++++++----- 3 files changed, 124 insertions(+), 34 deletions(-) diff --git a/src/core/resource/settings/modules/Settings.module.js b/src/core/resource/settings/modules/Settings.module.js index c18e6edbc..352699082 100644 --- a/src/core/resource/settings/modules/Settings.module.js +++ b/src/core/resource/settings/modules/Settings.module.js @@ -5,10 +5,39 @@ const stateName = 'settings'; const notifiactionsName = 'notifications'; const actionPrefix = stateName.toUpperCase(); const notificationsPrefix = notifiactionsName.toUpperCase(); -const initialState = {}; +const initialState = { + init: false, + updated: 0, + notifications: { + allAppSound: true, + allMessageNotifications: true, + allGroupEventsNotifications: true, + allIncomingCallNotifications: true, + allOthernotifications: true, + muteUnmuteDuringCallNotifications: true, + }, +}; +// Helpers START const initApply = data => data; +const getSettingsLocalStorage = () => { + let data = {}; + + try { + data = JSON.parse(localStorage.getItem(stateName)) || {} + } catch (e) { } + + return data; +}; + +const updateSettingsLocalStorage = ({ settings }) => { + try { + localStorage.setItem(stateName, JSON.stringify(settings)); + } catch (e) { } +}; +// Helpers END + // Selectors START const getInstance = (state) => { const instance = state[stateName] || {}; @@ -19,15 +48,15 @@ const getInstance = (state) => { }; const pullReceivedSettingsList = ({ settings = [] }) => { - const data = {}; + // Getting initial settings from localStorage until backend implement saving in DB + const data = getSettingsLocalStorage(); - Object.assign(data, { + const result = Object.assign(data, { init: true, updated: (new Date()).getTime(), - notifications: {} }); - return data; + return result; }; const getNotificationsSettings = (state) => { @@ -39,22 +68,31 @@ const getNotificationsSettings = (state) => { // Actions START const init = createAction(`${actionPrefix}_INIT`, initApply); const updateNotificationsSettings = createAction(`${actionPrefix}_${notificationsPrefix}_UPDATE`, initApply); +const updateLocalStorage = createAction(`${actionPrefix}_UPDATE_LOCAL_STORAGE`, updateSettingsLocalStorage); // Actions END // Handlers START const defaultMergeHandler = (state, payload) => merge(state, payload); const updateNotificationsSettingsHandler = (state, payload) => { - return Object.assign({}, state, - merge(state, { - [notifiactionsName]: { - [payload.setting]: payload.value + const newState = Object.assign( + {}, + state, + merge( + state, + { + [notifiactionsName]: { + [payload.setting]: payload.value + } } - }), + ), { init: true, updated: (new Date()).getTime() - }); + } + ); + + return newState; }; // Handlers END @@ -66,6 +104,7 @@ const settings = createReducer({ const settingsActions = { init, updateNotificationsSettings, + updateLocalStorage, }; const settingsSelectors = { diff --git a/src/core/resource/settings/sagas/Settings.saga.js b/src/core/resource/settings/sagas/Settings.saga.js index e730f1938..da389932b 100644 --- a/src/core/resource/settings/sagas/Settings.saga.js +++ b/src/core/resource/settings/sagas/Settings.saga.js @@ -1,11 +1,16 @@ -import { take, takeEvery, call, put, select } from 'redux-saga/effects'; +import { takeEvery, put, select } from 'redux-saga/effects'; +import { settingsActions, settingsSelectors } from '../index'; -function* updateNotificationsSettings() { - // TODO +function* updateNotificationsSettings({ payload }) { + const settings = yield select(settingsSelectors.getInstance); + yield put(settingsActions.updateLocalStorage({ settings })); } function* updateNotificationsSettingsWatcher() { - // TODO + yield takeEvery( + settingsActions.updateNotificationsSettings.getType(), + updateNotificationsSettings + ); } export { diff --git a/src/layouts/Notifications/Notifications.js b/src/layouts/Notifications/Notifications.js index a2f9b8154..dedea0121 100644 --- a/src/layouts/Notifications/Notifications.js +++ b/src/layouts/Notifications/Notifications.js @@ -1,27 +1,46 @@ -import React, { PureComponent, Component } from 'react'; +import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; +import { bindActionCreators } from 'redux'; import { withStyles } from 'material-ui/styles'; import { Switch } from 'material-ui' import stylesFunc from './Notifications.styles'; import Helmet from 'react-helmet'; import { SliderPanel } from '../../containers'; import translations from '../../assets/languages/Noifications/Notifications.en'; -import LocalizeHOC from "../../containers/LocalizeHOC"; +import LocalizeHOC from '../../containers/LocalizeHOC'; +import isEqual from 'lodash/isEqual'; +import { settingsSelectors, settingsActions } from '../../core/resource/settings/index'; const styles = theme => (stylesFunc(theme)); +const mapStateToProps = (state) => { + const notifications = settingsSelectors.getNotificationsSettings(state); + + return { + notifications, + }; +}; + +const mapDispatchToProps = dispatch => ({ + actions: bindActionCreators({ + ...settingsActions + }, dispatch), +}); + export class Notifications extends Component { constructor(props) { super(props); this.state = { - allAppSound: true, - allMessageNotifications: true, - allGroupEventsNotifications: true, - allIncomingCallNotifications: true, - allOthernotifications: true, - muteUnmuteDuringCallNotifications: true, + settings: { + allAppSound: true, + allMessageNotifications: true, + allGroupEventsNotifications: true, + allIncomingCallNotifications: true, + allOthernotifications: true, + muteUnmuteDuringCallNotifications: true, + }, panelsStatuses: { showIncomingMessageSoundsPanel: false, showGroupEventSoundsPanel: false, @@ -29,10 +48,26 @@ export class Notifications extends Component { showOtherNotificationsSoundsPanel: false, showMuteUnmuteDuringCallSoundPanel: false, }, - }; } + componentDidMount() { + const { notifications } = this.props; + if (Object.keys(notifications).length > 0) { + this.setState({ settings: notifications }); + } + } + + componentDidUpdate(prevProps, prevState) { + const prevSettings = prevProps.notifications; + const newSettings = this.props.notifications; + const isDifferent = isEqual(prevSettings, newSettings); + + if (!isDifferent) { + this.setState({ settings: newSettings }); + } + } + toggle(panelName) { const newStatuses = Object.assign({}, this.state.panelsStatuses); @@ -49,16 +84,24 @@ export class Notifications extends Component { this.setState({ panelsStatuses: newStatuses }); } - handleNotificationsChange = (notifications) => { + handleNotificationsChange = name => (event) => { + const { actions } = this.props; + actions.updateNotificationsSettings({ + setting: name, + value: event.target.checked + }); } render() { const { classes, translate } = this.props; + const { settings, panelsStatuses } = this.state; const { allAppSound, allMessageNotifications, allGroupEventsNotifications, allIncomingCallNotifications, - allOthernotifications, muteUnmuteDuringCallNotifications } = this.state; + allOthernotifications, muteUnmuteDuringCallNotifications + } = settings; const { showIncomingMessageSoundsPanel, showGroupEventSoundsPanel, showIncomingCallSoundsPanel, - showOtherNotificationsSoundsPanel, showMuteUnmuteDuringCallSoundPanel } = this.state.panelsStatuses; + showOtherNotificationsSoundsPanel, showMuteUnmuteDuringCallSoundPanel + } = panelsStatuses; return (
@@ -68,7 +111,7 @@ export class Notifications extends Component {
{translate('appSounds')} {translate('showNotifications')} {translate('showNotifications')} {translate('incomingCallSoundInMutedChat')} {translate('showNotifications')} {translate('notifications')} Date: Fri, 10 May 2019 13:43:56 +0300 Subject: [PATCH 11/33] NY-7377 [WEB] Push Notifications Manager --- .../managers/browserNotificationsManager.js | 56 +++++++++++++++++++ src/pages/NinjaApp/NinjaApp.js | 9 +-- 2 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 src/core/managers/browserNotificationsManager.js diff --git a/src/core/managers/browserNotificationsManager.js b/src/core/managers/browserNotificationsManager.js new file mode 100644 index 000000000..b2817410c --- /dev/null +++ b/src/core/managers/browserNotificationsManager.js @@ -0,0 +1,56 @@ +import { browserHistory } from 'react-router'; +import logoPng from 'Assets/img/logo.png'; + +/** + * Requests permission to show browser notifications + * + * @returns void + */ +const requestNotificationPermission = () => { + if (window.Notification && window.Notification.permission !== 'denied') { + window.Notification.requestPermission(); + } +}; + +/** + * Shows browser notification + * + * @param {String} body + * @param {String} type + * @param {String} redirectLink + * @param {String} title + * @param {String} icon + * @param {Function} callback + * @returns void + */ +const showNotification = (body, type, redirectLink = null, title = 'NYNJA', icon = null, callback = null) => { + const options = { + body: body, + icon: icon ? icon : logoPng + }; + + if (type) { + options.tag = type; + } + + const notification = new window.Notification(title, options); + + notification.onclick = (event) => { + event.preventDefault(); + parent.focus(); + window.focus(); + + if (typeof redirectLink === 'string') { + browserHistory.push(redirectLink); + } + + if (typeof callback === 'function') { + callback(); + } + }; +}; + +export { + requestNotificationPermission, + showNotification +}; diff --git a/src/pages/NinjaApp/NinjaApp.js b/src/pages/NinjaApp/NinjaApp.js index 515e53289..ac106a20b 100644 --- a/src/pages/NinjaApp/NinjaApp.js +++ b/src/pages/NinjaApp/NinjaApp.js @@ -2,7 +2,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { MenuAppBar, ActionMenu } from '../../containers'; -import { Grid } from 'material-ui'; import { withStyles } from 'material-ui/styles'; import stylesFunc from './NinjaApp.styles'; import darkBgImg from '../../assets/img/bg/dark-mountains.jpg'; @@ -10,6 +9,7 @@ import { profileSelectors } from 'Resource/profile'; import { authActions } from 'Resource/credentials'; import { bindActionCreators } from 'redux'; import { AudioVideo } from '../../componets'; +import { requestNotificationPermission } from '../../core/managers/browserNotificationsManager'; const styles = theme => (stylesFunc(theme, darkBgImg)); @@ -26,7 +26,9 @@ export class Dashboard extends Component { classes: PropTypes.object.isRequired }; - componentWillMount() {} + componentDidMount() { + requestNotificationPermission(); + } renderChildren(globalProps, childProps) { return React.cloneElement(globalProps, childProps); @@ -46,9 +48,8 @@ export class Dashboard extends Component { /> - { this.renderChildren(children, { personalData }) } + {this.renderChildren(children, { personalData })}
- ); } } -- GitLab From 174a62bb43a2c815e65059c3848ac737c4564319 Mon Sep 17 00:00:00 2001 From: RossyB Date: Fri, 10 May 2019 14:36:04 +0300 Subject: [PATCH 12/33] NY-7229 WEB A long message disrupts design --- src/containers/ChatBottomPanel/ChatBottomPanel.styles.js | 8 ++++++-- src/containers/ChatBottomPanel/Mentions.styles.js | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/containers/ChatBottomPanel/ChatBottomPanel.styles.js b/src/containers/ChatBottomPanel/ChatBottomPanel.styles.js index 32aae8e07..2ef34387d 100644 --- a/src/containers/ChatBottomPanel/ChatBottomPanel.styles.js +++ b/src/containers/ChatBottomPanel/ChatBottomPanel.styles.js @@ -47,7 +47,8 @@ export default theme => ({ boxShadow: '0 0 30px 30px #151619' }, inputWrap: { - flex: '1 0 auto' + flex: '1 0 auto', + maxWidth: 'calc(100% - 133px)' }, input: { zIndex: 1, @@ -61,7 +62,10 @@ export default theme => ({ borderRadius: 6, background: '#35383e', width: '100%', - maxWidth: '626px' + maxWidth: '626px', + '& textarea': { + overflow: 'hidden', + } }, allowMediaOpenImg: { maxWidth: '100% !important' diff --git a/src/containers/ChatBottomPanel/Mentions.styles.js b/src/containers/ChatBottomPanel/Mentions.styles.js index 693bd0301..177224f91 100644 --- a/src/containers/ChatBottomPanel/Mentions.styles.js +++ b/src/containers/ChatBottomPanel/Mentions.styles.js @@ -18,7 +18,7 @@ export default { border: 'none', color: '#ffffff', caretColor: '#b80000', - width: '98%', + width: '93%', maxWidth: 399, height: 32 } @@ -46,7 +46,7 @@ export default { caretColor: '#b80000', fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif', maxHeight: 64, - width: '98%' + width: '93%' } }, -- GitLab From 992c05541e18bc807e11085de1e157964d220b3d Mon Sep 17 00:00:00 2001 From: JelianRadoev Date: Fri, 10 May 2019 17:36:21 +0300 Subject: [PATCH 13/33] NY-7378 Notifications for received message P2P --- .../configs/BrowserNotifications.config.js | 2 + .../personal/sagas/PersonalMessages.saga.js | 63 ++++++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 src/core/configs/BrowserNotifications.config.js diff --git a/src/core/configs/BrowserNotifications.config.js b/src/core/configs/BrowserNotifications.config.js new file mode 100644 index 000000000..3db1eae05 --- /dev/null +++ b/src/core/configs/BrowserNotifications.config.js @@ -0,0 +1,2 @@ +export const P2P_CHAT_MESSAGE = 'p2p-chat-message'; +export const GROUP_CHAT_MESSAGE = 'group-chat-message'; diff --git a/src/core/resource/messages/personal/sagas/PersonalMessages.saga.js b/src/core/resource/messages/personal/sagas/PersonalMessages.saga.js index d88545bf0..05ca1ca99 100644 --- a/src/core/resource/messages/personal/sagas/PersonalMessages.saga.js +++ b/src/core/resource/messages/personal/sagas/PersonalMessages.saga.js @@ -6,11 +6,12 @@ import { p2pSelectors as selectors } from '../index'; import { queueActions } from '../../../app/index'; -import { userListActions } from 'Resource/userlist'; +import { userListActions, userListSelectors } from '../../../userlist/index'; import { profileSelectors } from 'Resource/profile'; import { supplierActions } from 'Resource/supplier'; import { openMessageModal } from '../../../notification/modules/notification'; import * as filesTypes from 'Core/configs/File.config'; +import * as notificationTypes from '../../../../configs/BrowserNotifications.config'; import { notificationActions } from 'Resource/notification'; import NynjaCommunicator from '../../../../SDK/nynjaCommunicator.sdk.js'; import { replySelector, replyActions } from 'Resource/messages/reply/index'; @@ -20,6 +21,8 @@ import { getVideoThumb, prepareContactData, isLink } from '../../utils/commonFun import saveAs from 'file-saver'; import { supplierSagas } from 'Resource/supplier'; import { credentialsSelectors, manageCredentialsActions } from 'Resource/credentials'; +import { showNotification } from '../../../../managers/browserNotificationsManager'; +import { settingsSelectors } from '../../../settings/index'; const uuidv4 = require('uuid/v4'); @@ -132,6 +135,15 @@ function* handleResponse(payload, rosterId) { if (payload.from === currentChatId && payload.from !== payload.to) { yield call(cursor, currentChatId); } + + // If message is not from the currently opened chat and its not sent by current user call notification saga + if (payload.from !== payload.to + && payload.to === userId + && window.location.pathname.indexOf(`/conversations/${payload.from}`) === -1 + && window.location.pathname.indexOf(`/chats/${payload.from}`) === -1 + ) { + yield call(handleNotifications, payload); + } } function* receiveP2PChatMessage() { @@ -502,6 +514,55 @@ function* exportToCsvWatcher() { yield takeEvery(actions.exportP2PChatToCsv.getType(), exportToCsv); } +function* handleNotifications(payload) { + const { allMessageNotifications } = yield select(settingsSelectors.getNotificationsSettings); + const { settings, names } = yield select(userListSelectors.getUserById, payload.from); + + let currentChatNotifications = settings.filter(el => el.key === 'Notifications')[0]; + currentChatNotifications = currentChatNotifications ? JSON.parse(currentChatNotifications.value) : true; + const isNotificationsEnabled = currentChatNotifications && allMessageNotifications; + + if (isNotificationsEnabled) { + let body = ''; + const { files } = payload; + + for (const k in files) { + if (files.hasOwnProperty(k)) { + const { mime, payload, id } = files[k]; + const isSystem = id.startsWith('srv_'); + + if (mime === filesTypes.TEXT && !isSystem) { + body = `${names}: ${payload}`; + break; + } else if (mime === filesTypes.IMAGE + || mime === filesTypes.VIDEO + || mime === filesTypes.FILE + || mime === filesTypes.AUDIO + || mime === filesTypes.STICKER + || mime === filesTypes.LOCATION + || mime === filesTypes.PLACE + || mime === filesTypes.CONTACT + ) { + body = `${names}: ${capitalize(mime)}`; + break; + } + } + } + + const type = notificationTypes.P2P_CHAT_MESSAGE; + const redirectLink = `/chats/${payload.from}`; + showNotification(body, type, redirectLink); + } +} + +const capitalize = (s) => { + if (typeof s !== 'string') { + return ''; + } + + return `${s.charAt(0).toUpperCase()}${s.slice(1)}`; +} + export { messageProcessingWatcher, messageDeleteWatcher, -- GitLab From 56c92d06b13a653f6c3f8c7e44a4d2611680519a Mon Sep 17 00:00:00 2001 From: JelianRadoev Date: Mon, 13 May 2019 11:22:12 +0300 Subject: [PATCH 14/33] move capitalize function to common functions --- .../personal/sagas/PersonalMessages.saga.js | 10 +--------- .../resource/messages/utils/commonFunctions.js | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/core/resource/messages/personal/sagas/PersonalMessages.saga.js b/src/core/resource/messages/personal/sagas/PersonalMessages.saga.js index 05ca1ca99..62a97dba5 100644 --- a/src/core/resource/messages/personal/sagas/PersonalMessages.saga.js +++ b/src/core/resource/messages/personal/sagas/PersonalMessages.saga.js @@ -17,7 +17,7 @@ import NynjaCommunicator from '../../../../SDK/nynjaCommunicator.sdk.js'; import { replySelector, replyActions } from 'Resource/messages/reply/index'; import { getStore } from '../../../../store/index'; import { fileStore } from 'Core/resource/messages/files/modules/Store.module'; -import { getVideoThumb, prepareContactData, isLink } from '../../utils/commonFunctions.js'; +import { getVideoThumb, prepareContactData, isLink, capitalize } from '../../utils/commonFunctions.js'; import saveAs from 'file-saver'; import { supplierSagas } from 'Resource/supplier'; import { credentialsSelectors, manageCredentialsActions } from 'Resource/credentials'; @@ -555,14 +555,6 @@ function* handleNotifications(payload) { } } -const capitalize = (s) => { - if (typeof s !== 'string') { - return ''; - } - - return `${s.charAt(0).toUpperCase()}${s.slice(1)}`; -} - export { messageProcessingWatcher, messageDeleteWatcher, diff --git a/src/core/resource/messages/utils/commonFunctions.js b/src/core/resource/messages/utils/commonFunctions.js index 6d4085a6b..67aa00a92 100644 --- a/src/core/resource/messages/utils/commonFunctions.js +++ b/src/core/resource/messages/utils/commonFunctions.js @@ -206,6 +206,20 @@ function isLink(str) { return /^(ftp|http|https|rtsp):\/\/[^ "]+$/.test(str); } +/** + * Capitalizes the first character of the given string + * + * @param {String} s + * @returns {String} + */ +const capitalize = (s) => { + if (typeof s !== 'string') { + return ''; + } + + return `${s.charAt(0).toUpperCase()}${s.slice(1)}`; +} + export { getVideoThumb, prepareContactData, @@ -214,4 +228,5 @@ export { fileTypeStyling, getUploadType, isLink, + capitalize }; -- GitLab From 57375a8aa1b9c558e9b878f4cc07667ec61c3fca Mon Sep 17 00:00:00 2001 From: JelianRadoev Date: Mon, 13 May 2019 15:34:37 +0300 Subject: [PATCH 15/33] Change notifications in group fixes --- .../ConversationsList/ConversationsList.js | 10 +++--- src/containers/GroupOptions/GroupOptions.js | 31 ++++++++++--------- .../LanguageSettingsPanel.js | 4 +-- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/containers/ConversationsList/ConversationsList.js b/src/containers/ConversationsList/ConversationsList.js index 5b6ebe985..8448cc903 100644 --- a/src/containers/ConversationsList/ConversationsList.js +++ b/src/containers/ConversationsList/ConversationsList.js @@ -328,8 +328,8 @@ class ConversationsList extends Component { member = admins[phone_id]; } - const notifications = member.settings.filter(el => el.key === 'NOTIFICATIONS')[0]; - const value = notifications ? (notifications.value === 'true') ? true : false : false; + const notifications = member.settings.filter(el => el.group === 'GROUP_NOTIFICATIONS')[0]; + const value = notifications ? JSON.parse(notifications.value) : true; if (data === 'muteGroup') { return !value; @@ -482,8 +482,8 @@ class ConversationsList extends Component { member = admins[phone_id]; } - const notifications = member.settings.filter(el => el.key === 'NOTIFICATIONS')[0]; - const value = notifications ? (notifications.value === 'true') : false; + const notifications = member.settings.filter(el => el.group === 'GROUP_NOTIFICATIONS')[0]; + const value = notifications ? JSON.parse(notifications.value) : true; this.setState({ selectedGroup: selectedGroup.id, @@ -513,7 +513,7 @@ class ConversationsList extends Component { autoTranslateIncoming: autoTranslateIncoming ? JSON.parse(autoTranslateIncoming.value) : false, autoTranslateOutgoing: autoTranslateOutgoing ? autoTranslateOutgoing.value : 'Off', translateLang: translateLang ? translateLang.value : 'English:en', - notifications: !notificationsGroup ? true : false + notifications: !notificationsGroup }; actionsGroup.setNotifications(payload); diff --git a/src/containers/GroupOptions/GroupOptions.js b/src/containers/GroupOptions/GroupOptions.js index 65a26256b..18908ec92 100644 --- a/src/containers/GroupOptions/GroupOptions.js +++ b/src/containers/GroupOptions/GroupOptions.js @@ -178,6 +178,7 @@ const defaultState = { myRoomAliasUpdated: '', groupLink: '', contacts: {}, + notifications: true, displayAddModal: false, displayRemoveModal: false, displayPromoteModal: false, @@ -498,10 +499,11 @@ class GroupOptions extends PureComponent { myAlias = alias; const showCsvPanel = router.params.mode === modes.exportCsv; - const notifications = settings.filter(el => el.key === 'NOTIFICATIONS')[0]; + const notifications = settings.filter(el => el.group === 'GROUP_NOTIFICATIONS')[0]; + if (lastSelectedRoomName !== roomName) { this.setState({ - notifications: notifications ? notifications.value === "true" : false, + notifications: notifications ? JSON.parse(notifications.value) : true, myRoomAliasUpdated: alias, roomNameUpdated: props.room && props.room.name ? props.room.name : '', roomDescUpdated: props.room && props.room.description ? props.room.description : '', @@ -513,7 +515,7 @@ class GroupOptions extends PureComponent { } else { this.setState({ panelsStatuses: { ...this.state.panelsStatuses, showCsvPanel }, - notifications: notifications ? notifications.value === "true" : false, + notifications: notifications ? JSON.parse(notifications.value) : true, }); } } @@ -556,14 +558,14 @@ class GroupOptions extends PureComponent { } } - handleNotificationsChange = name => (event) => { - this.setState({ [name]: event.target.checked }, - () => this.submitNotificationsChange() + handleNotificationsChange = (event) => { + const newValue = event.target.checked; + this.setState({ notifications: newValue }, + () => this.submitNotificationsChange(newValue) ); }; - submitNotificationsChange = () => { - const { notifications } = this.state; + submitNotificationsChange = (notifications) => { const { getMemberSettings, room, actions } = this.props; const { settings, id } = getMemberSettings(); const autoTranslateIncoming = settings.filter(el => el.key === 'AUTO_TRANSLATE')[0]; @@ -576,7 +578,7 @@ class GroupOptions extends PureComponent { autoTranslateIncoming: autoTranslateIncoming ? JSON.parse(autoTranslateIncoming.value) : false, autoTranslateOutgoing: autoTranslateOutgoing ? autoTranslateOutgoing.value : 'Off', translateLang: translateLang ? translateLang.value : 'English:en', - notifications: notifications ? !notifications.value : false + notifications }; actions.setNotifications(payload); @@ -913,7 +915,7 @@ class GroupOptions extends PureComponent { roomDesc, roomDescUpdated, lastSelectedRoomName, myRoomAlias, myRoomAliasUpdated, groupLink, showControll, panelsStatuses, displayClearHistoryModal, displayDeleteAndClearHistoryModal, displayDeleteAndKeepHistoryModal, displayRemoveModal, displayPromoteModal, displayDemoteModal, displayPromoteBeforeLeavingModal, showMoreDesc, selectedAdmins, adminsToRemove, - activeDialogId, storageType + activeDialogId, storageType, notifications } = this.state; const { classes, translate, isAdmin, isBanned, router, room, connectionStatus @@ -946,10 +948,9 @@ class GroupOptions extends PureComponent { const disableChangeAliasBtn = this.validateEmptyAlias(); const roomDescShrinked = roomDesc ? `${roomDesc.substring(0, 100)}...` : ''; const showStorage = showimageStoragePanel || showvideoStoragePanel || showfileStoragePanel || showaudioStoragePanel || showcontactStoragePanel || showlocationStoragePanel || showlinkStoragePanel; - + return (
- { isAdmin ? @@ -1136,7 +1137,7 @@ class GroupOptions extends PureComponent { onClick={() => this.toggle('showNotificationsPanel')}> {translate('groupOptionsPanel.notifications')} - {this.state.notifications ? translate('notifications.unmute') : translate('notifications.mute')} + {notifications ? translate('notifications.unmute') : translate('notifications.mute')} @@ -1444,9 +1445,9 @@ class GroupOptions extends PureComponent {
{translate('groupOptionsPanel.notifications')}
diff --git a/src/containers/Panels/LanguageSettingsPanel/LanguageSettingsPanel.js b/src/containers/Panels/LanguageSettingsPanel/LanguageSettingsPanel.js index f730cf765..e883f1a12 100644 --- a/src/containers/Panels/LanguageSettingsPanel/LanguageSettingsPanel.js +++ b/src/containers/Panels/LanguageSettingsPanel/LanguageSettingsPanel.js @@ -166,7 +166,7 @@ class LanguageSettingsPanel extends Component { const autoTranscribe = data.filter(el => el.key === 'AUTO_TRANSCRIBE')[0]; const autoTranslateTranscribe = data.filter(el => el.key === 'AUTO_TRANSLATE_TRANSCRIBE')[0]; const transcribeLang = data.filter(el => el.key === 'TRANSCRIBE_LANGUAGE')[0]; - const notifications = data.filter(el => el.key === 'NOTIFICATIONS')[0]; + const notifications = data.filter(el => el.group === 'GROUP_NOTIFICATIONS')[0]; this.setState({ autoTranslateIncoming: autoTranslateIncoming ? JSON.parse(autoTranslateIncoming.value) : false, @@ -175,7 +175,7 @@ class LanguageSettingsPanel extends Component { autoTranscribe: autoTranscribe ? JSON.parse(autoTranscribe.value) : true, autoTranslateTranscribe: autoTranslateTranscribe ? JSON.parse(autoTranslateTranscribe.value) : false, transcribeLang: transcribeLang ? transcribeLang.value : 'English:en', - notifications: notifications ? JSON.parse(notifications.value) : false + notifications: notifications ? JSON.parse(notifications.value) : true }); } -- GitLab From ce58c2d79933f0db3de514c6f703db8a898ef64a Mon Sep 17 00:00:00 2001 From: JelianRadoev Date: Tue, 14 May 2019 09:44:33 +0300 Subject: [PATCH 16/33] NY-7378 [WEB] Notifications for received message in group chats --- .../groups/sagas/GroupsMessages.saga.js | 154 +++++++++--------- 1 file changed, 77 insertions(+), 77 deletions(-) diff --git a/src/core/resource/messages/groups/sagas/GroupsMessages.saga.js b/src/core/resource/messages/groups/sagas/GroupsMessages.saga.js index c12415cee..3502d50c9 100644 --- a/src/core/resource/messages/groups/sagas/GroupsMessages.saga.js +++ b/src/core/resource/messages/groups/sagas/GroupsMessages.saga.js @@ -1,27 +1,25 @@ import { take, call, put, select, race, takeEvery } from 'redux-saga/effects'; import { delay } from 'redux-saga'; -import { - groupApi as api, - roomActions as actions, - roomsSelectors as selectors, -} from '../index'; -import { - p2pApi, -} from '../../personal/index'; +import { roomActions as actions, roomsSelectors as selectors } from '../index'; +import { p2pApi } from '../../personal/index'; import { queueActions } from '../../../app/index'; import { profileSelectors } from 'Resource/profile'; import { supplierActions } from 'Resource/supplier'; import { credentialsSelectors } from 'Resource/credentials'; import { openMessageModal } from "../../../notification/modules/notification"; -import * as filesTypes from 'Core/configs/File.config'; import { uploadActions } from '../../files'; -import NynjaCommunicator from '../../../../SDK/nynjaCommunicator.sdk.js'; import { replySelector, replyActions } from 'Resource/messages/reply/index'; -const uuidv4 = require('uuid/v4'); +import { settingsSelectors } from '../../../settings/index'; +import { roomListSelectors } from '../../../roomlist/index'; import { fileStore } from 'Core/resource/messages/files/modules/Store.module'; import { getStore } from '../../../../store/index'; -import { getVideoThumb, prepareContactData, isLink } from '../../utils/commonFunctions.js'; +import { getVideoThumb, prepareContactData, isLink, capitalize } from '../../utils/commonFunctions.js'; +import * as filesTypes from 'Core/configs/File.config'; +import * as notificationTypes from '../../../../configs/BrowserNotifications.config'; +import NynjaCommunicator from '../../../../SDK/nynjaCommunicator.sdk.js'; +import { showNotification } from '../../../../managers/browserNotificationsManager'; +const uuidv4 = require('uuid/v4'); function* send(data) { const encoded = yield call(p2pApi.processSend, data); yield put(supplierActions.send(encoded)); @@ -272,45 +270,22 @@ function* receiveGroupChatMessage() { yield put(actions.recieve({ payload: messagePayload.data })); + + const messageSender = messagePayload.data.from; + const groupId = messagePayload.data.to; + + // If message is not from the currently opened group and its not sent by current user call notification saga + if (messageSender !== phoneId + && window.location.pathname.indexOf(`/conversations/${groupId}`) === -1 + && window.location.pathname.indexOf(`/groups/${groupId}`) === -1) { + yield call(handleNotifications, messagePayload.data); + } } } } - // yield put(roomListActions.newMessage({ - // rosterId: yield select(profileSelectors.getActiveRosterId), - // payload: messagePayload.data - // })); - } } -//function * messageProcessingWatcher() { -// try { -// while (true) { -// console.log('------------'); -// const { response, request } = yield race({ -// response: take(actions.messageResponse.getType()), -// request: take(actions.send.getType()) -// }); -// -// const rosterId = yield select(profileSelectors.getActiveRosterId); -// -// if (request) { -// yield call(handleRequest, request, rosterId); -// } -// if (response) { -// const { payload: messagePayload } = yield take(facade.getEventTypes().EVENT_NEW_GROUP_CHAT_MESSAGE); -// yield put(actions.recieve({ -// payload: messagePayload -// })); -// // yield call(handleResponse, response, rosterId); -// } -// -// } -// } catch(e) { -// -// } -//} - function* messageDeleteWatcher() { while (true) { const { responseIn, responseOut } = yield race({ @@ -331,6 +306,7 @@ function* messageDeleteWatcher() { } catch (e) { } } } + function* messageDeleteResponseWatcher() { while (true) { const facade = yield select(NynjaCommunicator.getInstance); @@ -347,38 +323,6 @@ function* messageDeleteResponseWatcher() { } } -// function * cursor(activeDialogId) { -// const phoneId = yield select(profileSelectors.getPhoneId); -// const rosterId = yield select(profileSelectors.getActiveRosterId); -// const lastMessage = yield select(selectors.getLastMessageByPhoneId, activeDialogId); -// const { from, to, id } = lastMessage; -// const encoded = yield call(historyApi.historyUpdate, { from, to, phoneId, id }); -// yield put(supplierActions.send(encoded)); - -// yield take(actions.responseUpdateCounters.getType()); -// } - -// function * cursorWatcher() { -// while(true) { -// yield take(actions.uploadMessages.getType()); -// yield delay(500); -// const activeRoomId = yield select(selectors.getActiveRoomId); -// yield call(cursor, activeRoomId); - -// const rosterId = yield select(profileSelectors.getActiveRosterId); -// const dialog = yield select(selectors.getDialogByPhoneId, activeRoomId); -// //tmp -// const data = { -// ...dialog, -// unread_amount: 0 -// }; -// yield put(actions.update({ phoneId: activeRoomId, rosterId, data })); - -// const messages = yield select(selectors.getMessagesByPhoneId, activeRoomId); -// yield put(actions.updateAllMessagesStatus({ phoneId: activeRoomId, rosterId, messages }, "is_unread")) -// } -// } - function* cursor(data) { try { const { phoneId, groupId, lastReadMessageId, state } = data; @@ -410,6 +354,62 @@ function* cursorWatcher() { } } +function* handleNotifications(payload) { + const ownPhoneId = yield select(profileSelectors.getPhoneId); + const roomId = payload.to; + const msgSenderId = payload.from; + const room = yield select(roomListSelectors.getRoomById, roomId); + const { allMessageNotifications, allGroupEventsNotifications } = yield select(settingsSelectors.getNotificationsSettings); + const { settings } = yield select(roomListSelectors.getMemberById, roomId, ownPhoneId); + const msgSender = yield select(roomListSelectors.getMemberById, roomId, msgSenderId); + let notifications = settings.filter(el => el.group === 'GROUP_NOTIFICATIONS')[0]; + notifications = notifications ? JSON.parse(notifications.value) : true; + + if (allMessageNotifications && room) { + let body = ''; + let senderName = ''; + let groupName = room.name; + const { files } = payload; + + if (msgSender) { + senderName = msgSender.alias ? msgSender.alias : msgSender.names; + } + + for (const k in files) { + if (files.hasOwnProperty(k)) { + const { mime, payload, id } = files[k]; + const isSystem = id.startsWith('srv_'); + + if (isSystem && notifications && allGroupEventsNotifications) { + // body = 'SYSTEM-MESSAGE'; + break; + } else if (mime === filesTypes.TEXT && !isSystem && notifications) { + body = `${senderName}@${groupName}: ${payload}`; + break; + } else if (mime === filesTypes.IMAGE + || mime === filesTypes.VIDEO + || mime === filesTypes.FILE + || mime === filesTypes.AUDIO + || mime === filesTypes.STICKER + || mime === filesTypes.LOCATION + || mime === filesTypes.PLACE + || mime === filesTypes.CONTACT + && notifications + ) { + body = `${senderName}@${groupName}: ${capitalize(mime)}`; + break; + } + } + } + + if (body.length > 0) { + const type = notificationTypes.GROUP_CHAT_MESSAGE; + const redirectLink = `/groups/${roomId}`; + showNotification(body, type, redirectLink); + } + } +} + export { //messageProcessingWatcher, sendGroupChatMessage, -- GitLab From 15801fdd4a7d7fa7877d0379398b73896bb2ec7b Mon Sep 17 00:00:00 2001 From: JelianRadoev Date: Tue, 14 May 2019 10:52:27 +0300 Subject: [PATCH 17/33] NY-7379 [WEB] Group Events Notifications (create group) --- .../configs/BrowserNotifications.config.js | 1 + .../resource/roomlist/sagas/Rooms.saga.js | 29 ++++++++++++++----- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/core/configs/BrowserNotifications.config.js b/src/core/configs/BrowserNotifications.config.js index 3db1eae05..cc83d79ea 100644 --- a/src/core/configs/BrowserNotifications.config.js +++ b/src/core/configs/BrowserNotifications.config.js @@ -1,2 +1,3 @@ export const P2P_CHAT_MESSAGE = 'p2p-chat-message'; export const GROUP_CHAT_MESSAGE = 'group-chat-message'; +export const GROUP_EVENT_MESSAGE = 'group-event-message'; diff --git a/src/core/resource/roomlist/sagas/Rooms.saga.js b/src/core/resource/roomlist/sagas/Rooms.saga.js index 18fcf5297..d8af3b3e0 100644 --- a/src/core/resource/roomlist/sagas/Rooms.saga.js +++ b/src/core/resource/roomlist/sagas/Rooms.saga.js @@ -1,6 +1,7 @@ import { take, takeEvery, call, put, select } from 'redux-saga/effects'; import { delay } from 'redux-saga'; import { profileSelectors } from 'Resource/profile'; +import { settingsSelectors } from '../../settings/index'; import { roomListActions } from '../modules/RoomList.module'; import { profileInitActions } from "../../profile"; import NynjaCommunicator from '../../../SDK/nynjaCommunicator.sdk.js'; @@ -11,6 +12,8 @@ import { getStore } from '../../../store/index'; import saveAs from 'file-saver'; import { supplierSagas } from 'Resource/supplier'; import { manageCredentialsActions } from 'Resource/credentials'; +import { showNotification } from '../../../managers/browserNotificationsManager'; +import * as notificationTypes from '../../../configs/BrowserNotifications.config'; const uuidv4 = require('uuid/v4'); @@ -28,10 +31,8 @@ function* loadGroupLink() { const groupLink = sessionStorage.getItem('groupLink'); if (groupLink) { sessionStorage.removeItem('groupLink'); - console.log('sessionStorage.groupLink: ', groupLink); yield browserHistory.push(`/group/join/${groupLink}`); } - } function* requestCreateNewGroup() { @@ -116,7 +117,6 @@ function* clearRoomChatHistoryRequest() { function* leaveAndKeepHistory() { while (true) { const request = yield take(roomListActions.leaveGroup.getType()); - const rosterId = yield select(profileSelectors.getActiveRosterId); if (request && request.payload) { // leave group yield put(queueActions.queueAdd({ @@ -133,7 +133,7 @@ function* leaveAndKeepHistory() { function* leaveAndClearHistory() { while (true) { const request = yield take(roomListActions.leaveAndClearGroup.getType()); - const rosterId = yield select(profileSelectors.getActiveRosterId); + if (request && request.payload) { // clear history // yield put(queueActions.queueAdd({ @@ -293,9 +293,7 @@ function* requestRoomDetails() { while (true) { const request = yield take(roomListActions.getDetails.getType()); - const facade = yield select(NynjaCommunicator.getInstance); if (request && request.payload && request.payload.id) { - const groupChatsManager = facade.getGroupChatsManager(); try { yield put(queueActions.queueAdd({ type: 0, @@ -337,8 +335,25 @@ function* responseIncommingRoom() { const currentUserId = yield select(profileSelectors.getPhoneId); const isCreator = roomPayload.data.admins[currentUserId]; + const creator = Object.values(roomPayload.data.admins)[0]; + const type = notificationTypes.GROUP_EVENT_MESSAGE; + const groupName = roomPayload.data.name; + const groupId = roomPayload.data.id; + const { allGroupEventsNotifications } = yield select(settingsSelectors.getNotificationsSettings); + if (isCreator) { - yield browserHistory.push(`/groups/${roomPayload.data.id}`); + yield browserHistory.push(`/groups/${groupId}`); + if (allGroupEventsNotifications) { + const body = `You have created the group ${groupName}`; + showNotification(body, type); + } + } else { + if (allGroupEventsNotifications) { + const creatorName = creator ? creator.alias ? creator.alias : creator.names : ''; + const redirectLink = `/groups/${groupId}`; + const body = `${creatorName} invited you to the group ${groupName}`; + showNotification(body, type, redirectLink); + } } } } catch (error) { -- GitLab From fd53825dd7254a9ccbde5fefadba6063b2899e78 Mon Sep 17 00:00:00 2001 From: JelianRadoev Date: Tue, 14 May 2019 13:48:14 +0300 Subject: [PATCH 18/33] NY-7379 [WEB] Group Events Notifications (update name, avatar, description) --- .../resource/roomlist/sagas/Rooms.saga.js | 67 +++++++++++++++++-- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/src/core/resource/roomlist/sagas/Rooms.saga.js b/src/core/resource/roomlist/sagas/Rooms.saga.js index d8af3b3e0..739a0cf57 100644 --- a/src/core/resource/roomlist/sagas/Rooms.saga.js +++ b/src/core/resource/roomlist/sagas/Rooms.saga.js @@ -2,7 +2,7 @@ import { take, takeEvery, call, put, select } from 'redux-saga/effects'; import { delay } from 'redux-saga'; import { profileSelectors } from 'Resource/profile'; import { settingsSelectors } from '../../settings/index'; -import { roomListActions } from '../modules/RoomList.module'; +import { roomListActions, roomListSelectors } from '../modules/RoomList.module'; import { profileInitActions } from "../../profile"; import NynjaCommunicator from '../../../SDK/nynjaCommunicator.sdk.js'; import { queueActions } from '../../app/index'; @@ -87,9 +87,67 @@ function* responseUpdateRoom() { const facade = yield select(NynjaCommunicator.getInstance); const { payload: roomPayload } = yield take(facade.getEventTypes().EVENT_UPDATE_GROUP_CHAT); const rosterId = yield select(profileSelectors.getActiveRosterId); - yield put(queueActions.queueRem(`group-avatar-update-${roomPayload.data.id}`)); - yield put(queueActions.queueRem(`group-name-update-${roomPayload.data.id}`)); - yield put(queueActions.queueRem(`group-description-update-${roomPayload.data.id}`)); + const groupId = roomPayload.data.id; + + const avatarUpdateJobKey = `group-avatar-update-${groupId}`; + const groupNameUpdateJobKey = `group-name-update-${groupId}`; + const groupDescUpdateJobKey = `group-description-update-${groupId}` + + const isAvatarUpdateJob = yield call(getQueueJob, avatarUpdateJobKey); + const isGroupNameUpdateJob = yield call(getQueueJob, groupNameUpdateJobKey); + const isGroupDescUpdateJob = yield call(getQueueJob, groupDescUpdateJobKey); + const { allGroupEventsNotifications } = yield select(settingsSelectors.getNotificationsSettings); + + yield put(queueActions.queueRem(avatarUpdateJobKey)); + yield put(queueActions.queueRem(groupNameUpdateJobKey)); + yield put(queueActions.queueRem(groupDescUpdateJobKey)); + + // If the update is not caused by the currently logged user and he is not curretnly viewing the group + if ( + !isAvatarUpdateJob + && !isGroupNameUpdateJob + && !isGroupDescUpdateJob + && allGroupEventsNotifications + && window.location.pathname.indexOf(`/conversations/${groupId}`) === -1 + && window.location.pathname.indexOf(`/groups/${groupId}`) === -1 + ) { + const groupBeforeUpdate = yield select(roomListSelectors.getRoomById, groupId); + const groupAfterUpdate = roomPayload.data; + const groupName = groupBeforeUpdate.name; + const lastMsgSenderId = groupBeforeUpdate ? groupBeforeUpdate.last_msg.from : ''; + const lastMsgSender = groupBeforeUpdate ? groupBeforeUpdate.admins[lastMsgSenderId] : undefined; + const lastMsgSenderName = lastMsgSender ? lastMsgSender.alias ? lastMsgSender.alias : lastMsgSender.names : 'Admin'; + const type = notificationTypes.GROUP_EVENT_MESSAGE; + const redirectLink = `/groups/${groupId}`; + + let isAvatarUpdate = false; + let isNameUpdate = false; + let isDescUpdate = false; + + try { + isAvatarUpdate = groupBeforeUpdate.data[0].payload !== groupAfterUpdate.data[0].payload; + isNameUpdate = groupBeforeUpdate.name !== groupAfterUpdate.name; + isDescUpdate = groupBeforeUpdate.tos !== groupAfterUpdate.tos; + } catch (e) { + console.log('[Showing-Notifications-Error]', e); + } + + if (isAvatarUpdate) { + const body = `${lastMsgSenderName} edited the group's ${groupName} photo`; + showNotification(body, type, redirectLink); + } + + if (isNameUpdate) { + const body = `${lastMsgSenderName} edited the group's ${groupName} name`; + showNotification(body, type, redirectLink); + } + + if (isDescUpdate) { + const body = `${lastMsgSenderName} edited the group's ${groupName} description`; + showNotification(body, type, redirectLink); + } + } + yield put(roomListActions.update({ id: rosterId, payload: roomPayload.data @@ -235,7 +293,6 @@ function* requestUpdateRoom() { * if groupName payload should have groupId, groupName * if groupDescription payload should have groupId, groupDescription */ - if (roomId && imageBlob) { // Send request to update group avata let fileUrl; -- GitLab From 7c14a3f5b827412ddc6dc3e98b6c626c5aaa7498 Mon Sep 17 00:00:00 2001 From: Nicolas Berthet Date: Tue, 14 May 2019 20:38:56 +0800 Subject: [PATCH 19/33] Replace mqtt ip by hostname in dev deployment --- releases/dev/nynja-app-web.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releases/dev/nynja-app-web.yaml b/releases/dev/nynja-app-web.yaml index 559d97948..de8ee1234 100644 --- a/releases/dev/nynja-app-web.yaml +++ b/releases/dev/nynja-app-web.yaml @@ -28,7 +28,7 @@ spec: appleAppSiteAssociation: appId: 9GKQ5AMF2B.com.nynja.dev.mobile.communicator mqtt: - host: 34.221.152.42 + host: nynja-dev-uw2-messaging01.dev-eu.nynja.net confcall: service: calling-service.callconf.svc.cluster.local historyService: calling-service-history.callconf.svc.cluster.local -- GitLab From 6bafeeb9e2fcf73a5e4068f7627da894413a007d Mon Sep 17 00:00:00 2001 From: RossyB Date: Tue, 14 May 2019 17:13:23 +0300 Subject: [PATCH 20/33] move GroupOptions NY-7391 WEB GroupOptions-Storage --- .../ContactStorage/ContactStorage.js | 5 ++- .../ContactStorage/ContactStorage.styles.js | 5 ++- src/containers/GroupOptions/GroupOptions.js | 45 +++++++++++-------- .../GroupsMainArea/GroupsMainArea.js | 7 --- src/layouts/Conversations/Conversations.js | 7 +-- 5 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/containers/ContactStorage/ContactStorage.js b/src/containers/ContactStorage/ContactStorage.js index dc2e8aeac..efc4b6f2d 100644 --- a/src/containers/ContactStorage/ContactStorage.js +++ b/src/containers/ContactStorage/ContactStorage.js @@ -312,7 +312,8 @@ class ContactStorage extends Component { storageType, dialogId, isGroup, - storageLoading + storageLoading, + fromGroupOptions } = this.props; const { showPreview, previewFile, showShare } = this.state; @@ -335,7 +336,7 @@ class ContactStorage extends Component { className={this.props.storageArrowClassname} onClick={this.props.toggleStorage} > - + { storageLoading && diff --git a/src/containers/ContactStorage/ContactStorage.styles.js b/src/containers/ContactStorage/ContactStorage.styles.js index 0a0bef912..e68a2884f 100644 --- a/src/containers/ContactStorage/ContactStorage.styles.js +++ b/src/containers/ContactStorage/ContactStorage.styles.js @@ -182,7 +182,7 @@ export default (theme, avatarPic) => ({ padding: 20, color: '#3386EA', borderBottom: '1px solid #000', - whiteSpace: 'nowrap', + whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', '&:hover': { @@ -192,4 +192,7 @@ export default (theme, avatarPic) => ({ color: '#3386EA', } }, + hide: { + display: 'none !important' + } }); diff --git a/src/containers/GroupOptions/GroupOptions.js b/src/containers/GroupOptions/GroupOptions.js index 65a26256b..d867d59b3 100644 --- a/src/containers/GroupOptions/GroupOptions.js +++ b/src/containers/GroupOptions/GroupOptions.js @@ -228,7 +228,7 @@ class GroupOptions extends PureComponent { // this.setState({ [`${stateName}`]: !this.state[stateName] }); // } - toggle(panelName) { + toggle(panelName, callback) { const { router } = this.props; const newStatuses = Object.assign({}, this.state.panelsStatuses); @@ -246,7 +246,11 @@ class GroupOptions extends PureComponent { } } - this.setState({ panelsStatuses: newStatuses }); + this.setState({ panelsStatuses: newStatuses }, () => { + if (callback) { + callback(); + } + }); } toggleModal = () => { @@ -497,7 +501,8 @@ class GroupOptions extends PureComponent { const { settings, alias } = getMemberSettings(); myAlias = alias; - const showCsvPanel = router.params.mode === modes.exportCsv; + const panelsStatuses = this.state.panelsStatuses; + panelsStatuses.showAdminsPanel = router.params.mode === modes.exportCsv; const notifications = settings.filter(el => el.key === 'NOTIFICATIONS')[0]; if (lastSelectedRoomName !== roomName) { this.setState({ @@ -506,13 +511,13 @@ class GroupOptions extends PureComponent { roomNameUpdated: props.room && props.room.name ? props.room.name : '', roomDescUpdated: props.room && props.room.description ? props.room.description : '', lastSelectedRoomName: roomName, - panelsStatuses: { ...this.state.panelsStatuses, showCsvPanel }, + panelsStatuses, groupLink, groupLinkShort: linkId, }); } else { this.setState({ - panelsStatuses: { ...this.state.panelsStatuses, showCsvPanel }, + panelsStatuses, notifications: notifications ? notifications.value === "true" : false, }); } @@ -773,21 +778,22 @@ class GroupOptions extends PureComponent { handleStorageItemClick = (storageType) => { const { actions } = this.props; + + const callback = () => { + const data = { + type: storageType, + dialogId: this.props.router.params.id || this.props.router.params.phone_id, + isGroup: true + }; - this.toggle(`show${storageType}StoragePanel`); - - const data = { - type: storageType, - dialogId: this.props.router.params.id || this.props.router.params.phone_id, - isGroup: true - }; - - this.setState({ - storageType, - activeDialogId: data.dialogId - }); + this.setState({ + storageType, + activeDialogId: data.dialogId + }); - actions.getStorage(data); + actions.getStorage(data); + } + this.toggle(`show${storageType}StoragePanel`, callback); } closeAllModals = () => { @@ -946,7 +952,7 @@ class GroupOptions extends PureComponent { const disableChangeAliasBtn = this.validateEmptyAlias(); const roomDescShrinked = roomDesc ? `${roomDesc.substring(0, 100)}...` : ''; const showStorage = showimageStoragePanel || showvideoStoragePanel || showfileStoragePanel || showaudioStoragePanel || showcontactStoragePanel || showlocationStoragePanel || showlinkStoragePanel; - + return (
@@ -1371,6 +1377,7 @@ class GroupOptions extends PureComponent { storageType={storageType} dialogId={activeDialogId} isGroup={true} + fromGroupOptions={true} /> diff --git a/src/containers/GroupsMainArea/GroupsMainArea.js b/src/containers/GroupsMainArea/GroupsMainArea.js index ac7cf4e00..50e0b8c56 100644 --- a/src/containers/GroupsMainArea/GroupsMainArea.js +++ b/src/containers/GroupsMainArea/GroupsMainArea.js @@ -15,7 +15,6 @@ import { ForwardMessagePanel, ScheduleMessagePanel, LanguageSelectDialog, - GroupOptions, MediaClipboardHandler } from '../../containers'; import stylesFunc from "./GroupsMainArea.styles"; @@ -343,15 +342,10 @@ class GroupsMainArea extends Component { storageType, expandChatFeature, showAlternativeHeader, - showGroupOptions, isBanned, translate, storageArrowClassname, toggleStorage, - isMarketplaceShown, - showStartGroupCall, - onStorageItemClick, - params, } = this.props; const { @@ -378,7 +372,6 @@ class GroupsMainArea extends Component { return (
- {!isMarketplaceShown && !showStartGroupCall && !isBanned && } } + {!isMarketplaceShown && !showStartGroupCall && !isBanned && } {!isMarketplaceShown && !showStartGroupCall && isGroup && } /> -- GitLab From 4ed23286c4a755b62d4f087c4eb3763494fdaa21 Mon Sep 17 00:00:00 2001 From: JelianRadoev Date: Tue, 14 May 2019 17:45:11 +0300 Subject: [PATCH 21/33] NY-7379 [WEB] Browser Notifications on updating group, avatar, name, description fix --- .../resource/roomlist/sagas/Rooms.saga.js | 82 +++++++++---------- 1 file changed, 37 insertions(+), 45 deletions(-) diff --git a/src/core/resource/roomlist/sagas/Rooms.saga.js b/src/core/resource/roomlist/sagas/Rooms.saga.js index 739a0cf57..9faaf6a0e 100644 --- a/src/core/resource/roomlist/sagas/Rooms.saga.js +++ b/src/core/resource/roomlist/sagas/Rooms.saga.js @@ -87,67 +87,59 @@ function* responseUpdateRoom() { const facade = yield select(NynjaCommunicator.getInstance); const { payload: roomPayload } = yield take(facade.getEventTypes().EVENT_UPDATE_GROUP_CHAT); const rosterId = yield select(profileSelectors.getActiveRosterId); + const ownPhoneId = yield select(profileSelectors.getPhoneId); const groupId = roomPayload.data.id; const avatarUpdateJobKey = `group-avatar-update-${groupId}`; const groupNameUpdateJobKey = `group-name-update-${groupId}`; const groupDescUpdateJobKey = `group-description-update-${groupId}` - const isAvatarUpdateJob = yield call(getQueueJob, avatarUpdateJobKey); - const isGroupNameUpdateJob = yield call(getQueueJob, groupNameUpdateJobKey); - const isGroupDescUpdateJob = yield call(getQueueJob, groupDescUpdateJobKey); const { allGroupEventsNotifications } = yield select(settingsSelectors.getNotificationsSettings); - - yield put(queueActions.queueRem(avatarUpdateJobKey)); - yield put(queueActions.queueRem(groupNameUpdateJobKey)); - yield put(queueActions.queueRem(groupDescUpdateJobKey)); + const { settings } = yield select(roomListSelectors.getMemberById, groupId, ownPhoneId); + let notifications = settings.filter(el => el.group === 'GROUP_NOTIFICATIONS')[0]; + notifications = notifications ? JSON.parse(notifications.value) : true; // If the update is not caused by the currently logged user and he is not curretnly viewing the group if ( - !isAvatarUpdateJob - && !isGroupNameUpdateJob - && !isGroupDescUpdateJob - && allGroupEventsNotifications + allGroupEventsNotifications + && notifications && window.location.pathname.indexOf(`/conversations/${groupId}`) === -1 && window.location.pathname.indexOf(`/groups/${groupId}`) === -1 ) { - const groupBeforeUpdate = yield select(roomListSelectors.getRoomById, groupId); - const groupAfterUpdate = roomPayload.data; - const groupName = groupBeforeUpdate.name; - const lastMsgSenderId = groupBeforeUpdate ? groupBeforeUpdate.last_msg.from : ''; - const lastMsgSender = groupBeforeUpdate ? groupBeforeUpdate.admins[lastMsgSenderId] : undefined; - const lastMsgSenderName = lastMsgSender ? lastMsgSender.alias ? lastMsgSender.alias : lastMsgSender.names : 'Admin'; - const type = notificationTypes.GROUP_EVENT_MESSAGE; - const redirectLink = `/groups/${groupId}`; - - let isAvatarUpdate = false; - let isNameUpdate = false; - let isDescUpdate = false; - - try { - isAvatarUpdate = groupBeforeUpdate.data[0].payload !== groupAfterUpdate.data[0].payload; - isNameUpdate = groupBeforeUpdate.name !== groupAfterUpdate.name; - isDescUpdate = groupBeforeUpdate.tos !== groupAfterUpdate.tos; - } catch (e) { - console.log('[Showing-Notifications-Error]', e); - } - - if (isAvatarUpdate) { - const body = `${lastMsgSenderName} edited the group's ${groupName} photo`; - showNotification(body, type, redirectLink); - } - - if (isNameUpdate) { - const body = `${lastMsgSenderName} edited the group's ${groupName} name`; - showNotification(body, type, redirectLink); - } - - if (isDescUpdate) { - const body = `${lastMsgSenderName} edited the group's ${groupName} description`; - showNotification(body, type, redirectLink); + const isAvatarUpdateJob = yield call(getQueueJob, avatarUpdateJobKey); + const isGroupNameUpdateJob = yield call(getQueueJob, groupNameUpdateJobKey); + const isGroupDescUpdateJob = yield call(getQueueJob, groupDescUpdateJobKey); + + if (!isAvatarUpdateJob && !isGroupNameUpdateJob && !isGroupDescUpdateJob) { + const groupBeforeUpdate = yield select(roomListSelectors.getRoomById, groupId); + const groupAfterUpdate = roomPayload.data; + const groupName = groupBeforeUpdate.name; + const lastMsgSenderId = groupBeforeUpdate ? groupBeforeUpdate.last_msg.from : ''; + const lastMsgSender = groupBeforeUpdate ? groupBeforeUpdate.admins[lastMsgSenderId] : undefined; + const lastMsgSenderName = lastMsgSender ? lastMsgSender.alias ? lastMsgSender.alias : lastMsgSender.names : 'Admin'; + const type = notificationTypes.GROUP_EVENT_MESSAGE; + const redirectLink = `/groups/${groupId}`; + const isNameUpdate = groupBeforeUpdate.name !== groupAfterUpdate.name; + const isDescUpdate = groupBeforeUpdate.tos !== groupAfterUpdate.tos; + const isAvatarUpdate = groupAfterUpdate.data.length > 0; + + if (isNameUpdate) { + const body = `${lastMsgSenderName} edited the group's ${groupName} name`; + showNotification(body, type, redirectLink); + } else if (isDescUpdate) { + const body = `${lastMsgSenderName} edited the group's ${groupName} description`; + showNotification(body, type, redirectLink); + } else if (isAvatarUpdate) { + const body = `${lastMsgSenderName} edited the group's ${groupName} photo`; + showNotification(body, type, redirectLink); + } } } + yield put(queueActions.queueRem(avatarUpdateJobKey)); + yield put(queueActions.queueRem(groupNameUpdateJobKey)); + yield put(queueActions.queueRem(groupDescUpdateJobKey)); + yield put(roomListActions.update({ id: rosterId, payload: roomPayload.data -- GitLab From 98c4c72e4f67a05ac5cf74836a6e58778cf7e044 Mon Sep 17 00:00:00 2001 From: JelianRadoev Date: Tue, 14 May 2019 18:04:16 +0300 Subject: [PATCH 22/33] NY-7378 [WEB] Notifications for received messages in Group fix --- .../resource/messages/groups/sagas/GroupsMessages.saga.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/resource/messages/groups/sagas/GroupsMessages.saga.js b/src/core/resource/messages/groups/sagas/GroupsMessages.saga.js index 3502d50c9..6af64d306 100644 --- a/src/core/resource/messages/groups/sagas/GroupsMessages.saga.js +++ b/src/core/resource/messages/groups/sagas/GroupsMessages.saga.js @@ -394,9 +394,10 @@ function* handleNotifications(payload) { || mime === filesTypes.LOCATION || mime === filesTypes.PLACE || mime === filesTypes.CONTACT - && notifications ) { - body = `${senderName}@${groupName}: ${capitalize(mime)}`; + if (notifications && !isSystem) { + body = `${senderName}@${groupName}: ${capitalize(mime)}`; + } break; } } -- GitLab From 259a011e1845149a8f4375ce1d243b4f729de179 Mon Sep 17 00:00:00 2001 From: RossyB Date: Tue, 14 May 2019 18:35:54 +0300 Subject: [PATCH 23/33] NY-7391 WEB Group options - Storage --- src/containers/GroupOptions/GroupOptions.js | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/containers/GroupOptions/GroupOptions.js b/src/containers/GroupOptions/GroupOptions.js index d867d59b3..a3645b810 100644 --- a/src/containers/GroupOptions/GroupOptions.js +++ b/src/containers/GroupOptions/GroupOptions.js @@ -3,7 +3,6 @@ import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import TextField from 'material-ui/TextField'; import { withStyles } from 'material-ui/styles'; -import { addTranslationForLanguage, getTranslate } from 'react-localize-redux'; import { Tabs, Tab, Button, Chip, Avatar, ExpansionPanel, ExpansionPanelDetails, ExpansionPanelSummary, Switch @@ -17,7 +16,6 @@ import { contactsActions, contactsSelectors } from 'Resource/contacts/index'; import { notificationActions } from 'Resource/notification'; import { SliderPanel, MembersList, MemberDetailsPanel, ContactStorage, ExportCsvPanel } from 'Containers'; import { FancyAvatar, SearchBar, Modal } from '../../componets'; -import * as ComponentJson from 'Assets/languages/Groups/GroupOptions.en.json'; import { withRouter } from 'react-router'; import modes from 'Assets/helpers/modes'; import CustomScroll from 'react-custom-scrollbars'; @@ -29,6 +27,8 @@ import * as filesType from 'Core/configs/File.config'; import { ContextMenu, Item } from 'react-contexify'; import 'react-contexify/dist/ReactContexify.min.css'; import { storageActions } from 'Core/resource/storage'; +import translations from 'Assets/languages/Groups/GroupOptions.en.json'; +import LocalizeHOC from "../../containers/LocalizeHOC"; const TRANSLATION_KEY_PATH = ''; @@ -215,9 +215,6 @@ const defaultState = { } }; -@connect(state => ({ - translate: getTranslate(state.locale) -})) class GroupOptions extends PureComponent { constructor(props) { super(props); @@ -480,7 +477,6 @@ class GroupOptions extends PureComponent { // if (this.state.roomName === '' && this.props.room && this.props.room.name) { // this.setState({ roomName: this.props.room.name }); // } - this.props.dispatch(addTranslationForLanguage(ComponentJson, 'en')); } componentWillReceiveProps(props) { @@ -778,8 +774,8 @@ class GroupOptions extends PureComponent { handleStorageItemClick = (storageType) => { const { actions } = this.props; - - const callback = () => { + + const getstorageData = () => { const data = { type: storageType, dialogId: this.props.router.params.id || this.props.router.params.phone_id, @@ -793,7 +789,7 @@ class GroupOptions extends PureComponent { actions.getStorage(data); } - this.toggle(`show${storageType}StoragePanel`, callback); + this.toggle(`show${storageType}StoragePanel`, getstorageData); } closeAllModals = () => { @@ -1711,7 +1707,8 @@ class GroupOptions extends PureComponent { } } +const localized = LocalizeHOC({ translations })(GroupOptions); export default connect( mapStateToProps, mapDispatchToProps -)(withStyles(styles)(withRouter(GroupOptions))); +)(withStyles(styles)(withRouter(localized))); -- GitLab From e4a419512d75f268cb7db73324513d572c8708cc Mon Sep 17 00:00:00 2001 From: RossyB Date: Wed, 15 May 2019 11:38:20 +0300 Subject: [PATCH 24/33] NY-7339 [WEB] Notification settings - UI --- src/layouts/Notifications/Notifications.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/layouts/Notifications/Notifications.js b/src/layouts/Notifications/Notifications.js index dedea0121..b406d207d 100644 --- a/src/layouts/Notifications/Notifications.js +++ b/src/layouts/Notifications/Notifications.js @@ -131,7 +131,7 @@ export class Notifications extends Component { value="allMessageNotifications" />
-
+ {/*
-
+
*/} {/* Group events */}

{translate('groupEvents')}

@@ -153,7 +153,7 @@ export class Notifications extends Component { value="allGroupEventsNotifications" />
-
+ {/*
-
+
*/} {/* Call Notifications */}

{translate('callNotifications')}

@@ -187,7 +187,7 @@ export class Notifications extends Component { value="allIncomingCallNotifications" />
-
+ {/*
-
+
*/} {/* Other Notifications */}

{translate('otherNotifications')}

@@ -209,7 +209,7 @@ export class Notifications extends Component { value="allOthernotifications" />
-
+ {/*
-
+
*/}
{/* Notifications Panel */} @@ -233,13 +233,13 @@ export class Notifications extends Component {
{/* Sound Panel */} -
{translate('notifications')}
-
+ */}
); } -- GitLab From e9afafe0d90fe793abbbd01c50416fb034de70ac Mon Sep 17 00:00:00 2001 From: JelianRadoev Date: Wed, 15 May 2019 14:48:02 +0300 Subject: [PATCH 25/33] NY-7379 Group Events Notifications (added to group, promoted/demoted) --- .../roomlist/modules/RoomList.module.js | 4 + .../resource/roomlist/sagas/Rooms.saga.js | 113 +++++++++++++++++- 2 files changed, 114 insertions(+), 3 deletions(-) diff --git a/src/core/resource/roomlist/modules/RoomList.module.js b/src/core/resource/roomlist/modules/RoomList.module.js index f46560a4d..27903fe5d 100644 --- a/src/core/resource/roomlist/modules/RoomList.module.js +++ b/src/core/resource/roomlist/modules/RoomList.module.js @@ -45,6 +45,10 @@ const getRoomById = (state, id) => { const getMemberById = (state, roomId, memberId) => { const room = getRoomById(state, roomId); + if (!room) { + return; + } + const totalMembers = { ...room.members, ...room.admins }; return totalMembers[memberId]; }; diff --git a/src/core/resource/roomlist/sagas/Rooms.saga.js b/src/core/resource/roomlist/sagas/Rooms.saga.js index 9faaf6a0e..76ee801d6 100644 --- a/src/core/resource/roomlist/sagas/Rooms.saga.js +++ b/src/core/resource/roomlist/sagas/Rooms.saga.js @@ -414,11 +414,118 @@ function* responseIncommingRoom() { function* responseIncommingRoomMember() { while (true) { const facade = yield select(NynjaCommunicator.getInstance); - const { payload: roomPayload } = yield take(facade.getEventTypes().EVENT_NEW_GROUP_CHAT_MEMBERS); - yield put(queueActions.queueRem(`room-add-members-${roomPayload.data.id}`)); - yield put(queueActions.queueRem(`room-update-member-status-${roomPayload.data.id}`)); const rosterId = yield select(profileSelectors.getActiveRosterId); + const ownPhoneId = yield select(profileSelectors.getPhoneId); + const groupId = roomPayload.data.id; + const { allGroupEventsNotifications } = yield select(settingsSelectors.getNotificationsSettings); + const { settings } = yield select(roomListSelectors.getMemberById, groupId, ownPhoneId); + let notifications = settings.filter(el => el.group === 'GROUP_NOTIFICATIONS')[0]; + notifications = notifications ? JSON.parse(notifications.value) : true; + + const addMembersJobKey = `room-add-members-${groupId}`; + const updateStatusJobKey = `room-update-member-status-${groupId}`; + + /** + * The response status from the server for adding new members/promoting members to admins/demoting admins to members + * is the same for all three actions so some magic have to be done in order to deduce for which action is the response + * MAGIC START + */ + if ( + allGroupEventsNotifications + && notifications + && window.location.pathname.indexOf(`/conversations/${groupId}`) === -1 + && window.location.pathname.indexOf(`/groups/${groupId}`) === -1 + ) { + const isAddMembersJob = yield call(getQueueJob, addMembersJobKey); + const isUpdateStatusJob = yield call(getQueueJob, updateStatusJobKey); + const type = notificationTypes.GROUP_EVENT_MESSAGE; + const redirectLink = `/groups/${groupId}`; + + if (!isAddMembersJob && !isUpdateStatusJob) { + const groupAfterUpdate = roomPayload.data; + const groupName = groupAfterUpdate.name; + const isPromotingAdmins = Object.keys(groupAfterUpdate.admins).length > 1; + + if (isPromotingAdmins) { + let isMyPromotion = false; + + for (const a in groupAfterUpdate.admins) { + if (groupAfterUpdate.admins.hasOwnProperty(a)) { + const element = groupAfterUpdate.admins[a]; + if (element.phone_id === ownPhoneId) { + isMyPromotion = true; + break; + } + } + } + + if (isMyPromotion) { + const body = `You have been promoted to an admin in group ${groupName}`; + showNotification(body, type, redirectLink); + } + } else { + const groupBeforeUpdate = yield select(roomListSelectors.getRoomById, groupId); + const oldLastMsg = groupBeforeUpdate.last_msg; + const newLastMsg = groupAfterUpdate.last_msg; + const adminAlias = groupAfterUpdate.admins['0'].alias; + let addedMembers = ''; + + let isAboutMe = false; + let isDemoting = false; + let isAdding = false; + + for (const m in groupAfterUpdate.members) { + if (groupAfterUpdate.members.hasOwnProperty(m)) { + const element = groupAfterUpdate.members[m]; + if (element.phone_id === ownPhoneId) { + isAboutMe = true; + } + addedMembers += element.alias ? element.alias : element.names; + } + } + + if (!groupBeforeUpdate) { + isAdding = true; + } else { + if (oldLastMsg && newLastMsg) { + const isOldSystem = oldLastMsg.msg_id.startsWith('srv_'); + const isNewSystem = newLastMsg.msg_id.startsWith('srv_'); + + if (!isNewSystem) { + isDemoting = true; + } else if (!isOldSystem) { + isAdding = true; + } else { + if (oldLastMsg.msg_id === newLastMsg.msg_id) { + isDemoting = true; + } else { + isAdding = true; + } + } + } + } + + if (isDemoting && isAboutMe) { + const body = `You have been demoted to a member in group ${groupName}`; + showNotification(body, type, redirectLink); + } + + if (isAdding) { + const body = isAboutMe + ? `${adminAlias} invited you to the group ${groupName}` + : `${adminAlias} added ${addedMembers} to the group ${groupName}`; + showNotification(body, type, redirectLink); + } + } + } + } + /** + * MAGIC END + */ + + yield put(queueActions.queueRem(addMembersJobKey)); + yield put(queueActions.queueRem(updateStatusJobKey)); if (roomPayload.data.tup === 'Room') { yield put(roomListActions.update({ -- GitLab From 32461ae9c7bf329a996ed1b87fae1e3115e7e7a5 Mon Sep 17 00:00:00 2001 From: JelianRadoev Date: Wed, 15 May 2019 15:05:04 +0300 Subject: [PATCH 26/33] NY-7407 [WEB] Provide the timezone in the request --- .../resource/messages/personal/sagas/PersonalMessages.saga.js | 1 + src/core/resource/roomlist/sagas/Rooms.saga.js | 1 + 2 files changed, 2 insertions(+) diff --git a/src/core/resource/messages/personal/sagas/PersonalMessages.saga.js b/src/core/resource/messages/personal/sagas/PersonalMessages.saga.js index 6349af2cc..b198bb0c4 100644 --- a/src/core/resource/messages/personal/sagas/PersonalMessages.saga.js +++ b/src/core/resource/messages/personal/sagas/PersonalMessages.saga.js @@ -486,6 +486,7 @@ function* exportToCsv({ payload }) { try { const facade = yield select(NynjaCommunicator.getInstance); const messagesManager = facade.getMessagesManager(); + filters.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; const res = yield messagesManager.getP2PChatCsv(to, filters); if (res.status === 200) { diff --git a/src/core/resource/roomlist/sagas/Rooms.saga.js b/src/core/resource/roomlist/sagas/Rooms.saga.js index 18fcf5297..e5dc7f816 100644 --- a/src/core/resource/roomlist/sagas/Rooms.saga.js +++ b/src/core/resource/roomlist/sagas/Rooms.saga.js @@ -588,6 +588,7 @@ function* exportToCsv({ payload }) { try { const facade = yield select(NynjaCommunicator.getInstance); const messagesManager = facade.getMessagesManager(); + filters.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; const res = yield messagesManager.getGroupChatCsv(roomId, filters); if (res.status === 200) { -- GitLab From dd86180a8ca2ad046cb81c19cc63094cb365a0a6 Mon Sep 17 00:00:00 2001 From: RossyB Date: Wed, 15 May 2019 18:47:52 +0300 Subject: [PATCH 27/33] NY-7223 WEB Audio player - scrolling --- .../Modals/MediaPreviewModal.en.json | 6 ++ .../MediaPreview/MediaPreview.js | 58 ++++++++++--------- 2 files changed, 36 insertions(+), 28 deletions(-) create mode 100644 src/assets/languages/Modals/MediaPreviewModal.en.json diff --git a/src/assets/languages/Modals/MediaPreviewModal.en.json b/src/assets/languages/Modals/MediaPreviewModal.en.json new file mode 100644 index 000000000..e8ab68308 --- /dev/null +++ b/src/assets/languages/Modals/MediaPreviewModal.en.json @@ -0,0 +1,6 @@ +{ + "share": "Share...", + "saveAs": "Save As...", + "showInMaps": "Show in Maps", + "close": "Close" +} \ No newline at end of file diff --git a/src/componets/Modals/PreviewModals/MediaPreview/MediaPreview.js b/src/componets/Modals/PreviewModals/MediaPreview/MediaPreview.js index 9de934786..c849280ce 100644 --- a/src/componets/Modals/PreviewModals/MediaPreview/MediaPreview.js +++ b/src/componets/Modals/PreviewModals/MediaPreview/MediaPreview.js @@ -8,6 +8,8 @@ import saveAs from 'file-saver'; import { profileSelectors } from 'Resource/profile'; import LinearProgress from 'material-ui/Progress/LinearProgress'; import { fileStore } from 'Core/resource/messages/files/modules/Store.module'; +import translations from 'Assets/languages/Modals/MediaPreviewModal.en'; +import LocalizeHOC from '../../../../containers/LocalizeHOC'; const mapStateToProps = (state) => { return { @@ -28,15 +30,6 @@ class MediaPreview extends Component { audioError: false, showOriginalMessage: true, }; - - this.toggleAudio = this.toggleAudio.bind(this); - this.toggleMute = this.toggleMute.bind(this); - this.audioTimeUpdate = this.audioTimeUpdate.bind(this); - this.audioMetadataLoaded = this.audioMetadataLoaded.bind(this); - this.onAudioError = this.onAudioError.bind(this); - this.onAudioEnd = this.onAudioEnd.bind(this); - this.pauseAudio = this.pauseAudio.bind(this); - this.jumpInTime = this.jumpInTime.bind(this); } componentDidMount() { @@ -65,25 +58,27 @@ class MediaPreview extends Component { document.removeEventListener("voicePlayStart", this.pauseAudio); } - pauseAudio(event) { + pauseAudio = (event) => { if (this.audio && JSON.stringify(event.data) != JSON.stringify(this.props.data) && !this.audio.paused && !this.audio.ended) { this.audio.pause(); this.setState({ playing: false }); } } - onAudioError() { + onAudioError = () => { this.setState({ audioError: true }); } - audioMetadataLoaded(event) { + audioMetadataLoaded = (event) => { const audio = event.currentTarget; self = this; + console.log('[TEMP] audio.duration', audio.duration); if (!audio.duration || audio.duration == Infinity) { audio.currentTime = 1e101; audio.ontimeupdate = function () { this.ontimeupdate = () => { return; } + try { if (audio.duration >= 60 * 60) { self.setState({ duration: new Date(audio.duration * 1000).toISOString().substr(11, 8) }); @@ -102,7 +97,7 @@ class MediaPreview extends Component { } } - audioTimeUpdate(event) { + audioTimeUpdate = (event) => { const audio = event.currentTarget; if (!audio.duration || audio.duration == Infinity) { @@ -124,17 +119,20 @@ class MediaPreview extends Component { } } - jumpInTime(event) { + jumpInTime = (event) => { if (this.state.audioError || !this.audio) { return; } - const rel = event.offsetX / event.currentTarget.childNodes[0].clientWidth; + const rel = event.layerX / event.currentTarget.childNodes[1].offsetWidth; + console.log('[TEMP] event.offsetX', event.offsetX); + console.log('[TEMP] event.layerX', event.layerX); + console.log('[TEMP] event.currentTarget', event.currentTarget); const jump = (this.audio.duration * rel) || 0; this.audio.currentTime = jump; } - toggleAudio() { + toggleAudio = () => { if (this.audio && !this.state.audioError) { if (this.audio.paused || this.audio.ended) { this.audio.play(); @@ -151,7 +149,7 @@ class MediaPreview extends Component { } } - toggleMute() { + toggleMute = () => { if (this.audio && !this.state.audioError) { this.audio.muted = !this.audio.muted; this.setState(prevState => ({ @@ -160,7 +158,7 @@ class MediaPreview extends Component { } } - onAudioEnd() { + onAudioEnd = () => { setTimeout(() => { this.setState({ playing: false, audioProgress: 0 }); }, 500); @@ -171,7 +169,7 @@ class MediaPreview extends Component { } render() { - const { classes, showModal, onCloseModal, fileType, fileName, fileSize, fileCreated, locationURLS, onShare } = this.props; + const { classes, showModal, onCloseModal, fileType, fileName, fileSize, fileCreated, locationURLS, onShare, translate } = this.props; const { playing, muted, fileURL, audioProgress, duration } = this.state; let media; @@ -202,7 +200,9 @@ class MediaPreview extends Component { case filesType.AUDIO: media = (
-
-- GitLab From 6cac402030795ff8be88add62e13244c7df2d433 Mon Sep 17 00:00:00 2001 From: JelianRadoev Date: Thu, 16 May 2019 10:01:38 +0300 Subject: [PATCH 30/33] NY-7379 [WEB] Group Events Notifications (removed from group) --- .../resource/roomlist/sagas/Rooms.saga.js | 49 +++++++++++++++++-- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/src/core/resource/roomlist/sagas/Rooms.saga.js b/src/core/resource/roomlist/sagas/Rooms.saga.js index 772be3736..79b0353e4 100644 --- a/src/core/resource/roomlist/sagas/Rooms.saga.js +++ b/src/core/resource/roomlist/sagas/Rooms.saga.js @@ -478,10 +478,12 @@ function* responseIncommingRoomMember() { for (const m in groupAfterUpdate.members) { if (groupAfterUpdate.members.hasOwnProperty(m)) { const element = groupAfterUpdate.members[m]; + if (element.phone_id === ownPhoneId) { isAboutMe = true; } - addedMembers += element.alias ? element.alias : element.names; + + addedMembers += `${element.alias ? element.alias : element.names} `; } } @@ -510,7 +512,7 @@ function* responseIncommingRoomMember() { const body = `You have been demoted to a member in group ${groupName}`; showNotification(body, type, redirectLink); } - + if (isAdding) { const body = isAboutMe ? `${adminAlias} invited you to the group ${groupName}` @@ -670,10 +672,49 @@ function* responseJoinMemberToRoom() { function* responseRemoveMembersFromRoom() { while (true) { const facade = yield select(NynjaCommunicator.getInstance); - const { payload: roomPayload } = yield take(facade.getEventTypes().EVENT_GROUP_CHAT_MEMBERS_REMOVED); - yield put(queueActions.queueRem(`room-remove-members-${roomPayload.data.id}`)); const rosterId = yield select(profileSelectors.getActiveRosterId); + const ownPhoneId = yield select(profileSelectors.getPhoneId); + const groupId = roomPayload.data.id; + const removeMembersJobKey = `room-remove-members-${groupId}`; + const { allGroupEventsNotifications } = yield select(settingsSelectors.getNotificationsSettings); + const { settings } = yield select(roomListSelectors.getMemberById, groupId, ownPhoneId); + let notifications = settings.filter(el => el.group === 'GROUP_NOTIFICATIONS')[0]; + notifications = notifications ? JSON.parse(notifications.value) : true; + + yield put(queueActions.queueRem(removeMembersJobKey)); + + if ( + allGroupEventsNotifications + && notifications + && window.location.pathname.indexOf(`/conversations/${groupId}`) === -1 + && window.location.pathname.indexOf(`/groups/${groupId}`) === -1 + ) { + const groupName = roomPayload.data.name; + const redirectLink = `/groups/${groupName}`; + const type = notificationTypes.GROUP_EVENT_MESSAGE; + const admin = roomPayload.data.admins[0].alias ? roomPayload.data.admins[0].alias : roomPayload.data.admins[0].names; + let isAboutMe = false; + let body = ''; + let removedMembers = ''; + + for (const m of roomPayload.data.members) { + if (m.phone_id === ownPhoneId) { + isAboutMe = true; + } + + removedMembers += `${m.alias ? m.alias : m.names} `; + } + + if (isAboutMe) { + body = `${admin} removed you from the group ${groupName}`; + } else { + body = `${admin} removed ${removedMembers} from the group ${groupName}`; + } + + showNotification(body, type, redirectLink); + } + if (roomPayload.data.tup === 'Room') { yield put(roomListActions.updateRemovedMembers({ id: rosterId, -- GitLab From 4d9480ed51358b6878e410d80823700da60473cc Mon Sep 17 00:00:00 2001 From: JelianRadoev Date: Thu, 16 May 2019 11:52:43 +0300 Subject: [PATCH 31/33] NY-7379 [WEB] Group Events Notifications (leave group) --- .../resource/roomlist/sagas/Rooms.saga.js | 54 ++++++++++++++++--- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/src/core/resource/roomlist/sagas/Rooms.saga.js b/src/core/resource/roomlist/sagas/Rooms.saga.js index 79b0353e4..79923a475 100644 --- a/src/core/resource/roomlist/sagas/Rooms.saga.js +++ b/src/core/resource/roomlist/sagas/Rooms.saga.js @@ -208,25 +208,63 @@ function* leaveRoomResponse() { while (true) { const facade = yield select(NynjaCommunicator.getInstance); try { - const { - payload: roomPayload - } = yield take(facade.getEventTypes().EVENT_GROUP_CHAT_LEAVE); + const { payload: roomPayload } = yield take(facade.getEventTypes().EVENT_GROUP_CHAT_LEAVE); const rosterId = yield select(profileSelectors.getActiveRosterId); - const isQueueJob = yield call(getQueueJob, `group-leave-${roomPayload.data.id}`); - yield put(queueActions.queueRem(`group-leave-${roomPayload.data.id}`)); + const ownPhoneId = yield select(profileSelectors.getPhoneId); + const groupId = roomPayload.data.id; + const groupName = roomPayload.data.name; + const leaveGroupJobKey = `group-leave-${groupId}`; + const isQueueJob = yield call(getQueueJob, leaveGroupJobKey); + const type = notificationTypes.GROUP_EVENT_MESSAGE; + const redirectLink = `groups/${groupId}`; + + const { allGroupEventsNotifications } = yield select(settingsSelectors.getNotificationsSettings); + const { settings } = yield select(roomListSelectors.getMemberById, groupId, ownPhoneId); + let notifications = settings.filter(el => el.group === 'GROUP_NOTIFICATIONS')[0]; + notifications = notifications ? JSON.parse(notifications.value) : true; + + yield put(queueActions.queueRem(leaveGroupJobKey)); + if (isQueueJob) { const globalState = getStore().getState(); const rooms = globalState.roomlist[rosterId]; const baseUrl = window.location.href.indexOf('conversations') !== -1 ? 'conversations' : 'groups'; + if (rooms && roomPayload.data) { Object.values(rooms).forEach((room) => { - if (room.id === roomPayload.data.id) { + if (room.id === groupId) { delete rooms[room.id]; } }); + yield browserHistory.push(`/${baseUrl}`); } } + + if ( + allGroupEventsNotifications + && notifications + && window.location.pathname.indexOf(`/conversations/${groupId}`) === -1 + && window.location.pathname.indexOf(`/groups/${groupId}`) === -1 + ) { + if (isQueueJob) { + const body = `You have left the group ${groupName}`; + showNotification(body, type); + } else { + let leftNames = ''; + + for (const a of roomPayload.data.admins) { + leftNames += `${a.alias ? a.alias : a.names} `; + } + + for (const m of roomPayload.data.members) { + leftNames += `${m.alias ? m.alias : m.names} `; + } + + const body = `${leftNames}left group ${groupName}`; + showNotification(body, type, redirectLink); + } + } } catch (e) { console.log('clearRoomHistroryResponse: ', e); } @@ -478,7 +516,7 @@ function* responseIncommingRoomMember() { for (const m in groupAfterUpdate.members) { if (groupAfterUpdate.members.hasOwnProperty(m)) { const element = groupAfterUpdate.members[m]; - + if (element.phone_id === ownPhoneId) { isAboutMe = true; } @@ -697,7 +735,7 @@ function* responseRemoveMembersFromRoom() { let isAboutMe = false; let body = ''; let removedMembers = ''; - + for (const m of roomPayload.data.members) { if (m.phone_id === ownPhoneId) { isAboutMe = true; -- GitLab From a7f74310e63bfcd4eedab975aab61c7aac52ff74 Mon Sep 17 00:00:00 2001 From: JelianRadoev Date: Thu, 16 May 2019 15:10:49 +0300 Subject: [PATCH 32/33] NY-7380 [WEB] Contact Notifications (contact request, accepted request) --- .../configs/BrowserNotifications.config.js | 1 + .../contacts/modules/Contacts.module.js | 13 ---- .../resource/contacts/sagas/Contact.saga.js | 72 +++++++++++++------ 3 files changed, 52 insertions(+), 34 deletions(-) diff --git a/src/core/configs/BrowserNotifications.config.js b/src/core/configs/BrowserNotifications.config.js index cc83d79ea..0c0e3c569 100644 --- a/src/core/configs/BrowserNotifications.config.js +++ b/src/core/configs/BrowserNotifications.config.js @@ -1,3 +1,4 @@ export const P2P_CHAT_MESSAGE = 'p2p-chat-message'; export const GROUP_CHAT_MESSAGE = 'group-chat-message'; export const GROUP_EVENT_MESSAGE = 'group-event-message'; +export const OTHER_NOTIFICATIONS = 'other-notifications'; diff --git a/src/core/resource/contacts/modules/Contacts.module.js b/src/core/resource/contacts/modules/Contacts.module.js index 2c9e6eead..f95ebe635 100644 --- a/src/core/resource/contacts/modules/Contacts.module.js +++ b/src/core/resource/contacts/modules/Contacts.module.js @@ -1,10 +1,8 @@ import { createAction, createReducer } from 'redux-act'; -import has from 'lodash/has'; import { profileSelectors } from 'Resource/profile'; import { userListSelectors } from 'Resource/userlist'; import merge from 'deepmerge'; import map from 'lodash/map'; -import matches from 'lodash/matches'; import filter from 'lodash/filter'; const stateName = 'contacts'; @@ -104,15 +102,6 @@ const getAllRequestedContacts = (state) => { return getFullContactsByStatus(state, { status }); }; -// Deprecated -// const getAuthContactRequest = (state) => { -// const status = { -// is_authorized: true -// }; - -// return getFullContactsByStatus(state, { status }); -// }; - const getFriends = (state) => { const status = { is_friend: true @@ -167,7 +156,6 @@ const responseContactInternal = createAction('RESPONSE_CONTACT_INTERNAL'); const responseContactAuthorization = createAction('RESPONSE_CONTACT_AUTHORIZATION'); // Server action catch in saga const saveNewAuthorizationContactRequest = createAction('SAVE_NEW_AUTHORIZATION_CONTACT_REQUEST'); // Saga call save data to store - //-- const requestContact = createAction('REQUEST_CONTACT', acceptApply); const acceptContact = createAction('ACCEPT_CONTACT', acceptApply); @@ -177,7 +165,6 @@ const unblockContact = createAction('UNBLOCK_CONTACT', acceptApply); const muteContact = createAction('MUTE_CONTACT', initApply); const unmuteContact = createAction('UNMUTE_CONTACT', initApply); - const initHandler = (state, payload) => Object.assign( {}, state, diff --git a/src/core/resource/contacts/sagas/Contact.saga.js b/src/core/resource/contacts/sagas/Contact.saga.js index 3ebbfa51b..cea4f8d0e 100644 --- a/src/core/resource/contacts/sagas/Contact.saga.js +++ b/src/core/resource/contacts/sagas/Contact.saga.js @@ -1,16 +1,15 @@ -import { contactsActions } from '../modules/Contacts.module'; +import { contactsActions, contactsSelectors } from '../modules/Contacts.module'; import { userListActions } from '../../userlist/modules/UserList.module'; import { searchListActions } from '../../search/modules/SearchList.module'; import { credentialsSelectors } from '../../credentials/modules/Credentials.module'; import { delay } from 'redux-saga'; -import { take, call, put, select, race } from 'redux-saga/effects'; +import { take, put, select, race } from 'redux-saga/effects'; import { profileSelectors } from 'Resource/profile'; -import { generateSchema, processSend, processSearchSend } from '../api/ContactRequest.api'; -import { supplierActions } from 'Resource/supplier'; -import { p2pActions as actions } from '../../messages/personal'; import { openMessageModal, closeMessageModal } from '../../notification/modules/notification'; import NynjaCommunicator from '../../../SDK/nynjaCommunicator.sdk.js'; -import constants from '../../../configs/Constants.config'; +import { showNotification } from '../../../managers/browserNotificationsManager'; +import { settingsSelectors } from '../../settings/index'; +import * as notificationTypes from '../../../configs/BrowserNotifications.config'; function* requestContactAuthorization() { while (true) { @@ -18,7 +17,13 @@ function* requestContactAuthorization() { const rosterId = yield select(profileSelectors.getActiveRosterId); yield put(userListActions.saveNewUser({ rosterId: rosterId, payload })); yield put(contactsActions.responseContactUpdate({ rosterId: rosterId, payload: payload })); // Нет времени обьяснять))) - yield put(openMessageModal('New contact request')); + const { allOthernotifications } = yield select(settingsSelectors.getNotificationsSettings); + + if (allOthernotifications) { + const body = `${payload.names} ${payload.surnames} wants to add you on NYNJA!`; + const type = notificationTypes.OTHER_NOTIFICATIONS; + showNotification(body, type); + } } } @@ -346,18 +351,43 @@ function* handleContactUpdate() { const rosterId = yield select(profileSelectors.getActiveRosterId); - const contactsManager = facade.getContactsManager(); - // console.log('handle response', response); - if (response) { - // console.log('handle ContactUpdate', response); - yield put(userListActions.settingsUpdate({ id: rosterId, phoneId: response.payload._data.phone_id, ...response.payload._data })); - yield put(contactsActions.responseContactUpdate({ rosterId, payload: response.payload._data })); - yield put(searchListActions.updateContact({ id: rosterId, ...response.payload._data })); - // yield put(openMessageModal('Contact details updated')); + if (response) { + const { allOthernotifications } = yield select(settingsSelectors.getNotificationsSettings); + const ownPhoneId = yield select(profileSelectors.getPhoneId); + const contact = response.payload._data; + const contactId = contact.phone_id; + + let shouldNotify = false; + let isAlreadyFriend = false; + + if (allOthernotifications && ownPhoneId !== contactId) { + const friends = yield select(contactsSelectors.getFriends); + + for (const f of friends) { + if (f.phone_id === contactId) { + isAlreadyFriend = true; + break; + } + } + + if (!isAlreadyFriend) { + shouldNotify = true; + } + } + + yield put(userListActions.settingsUpdate({ id: rosterId, phoneId: contact.phone_id, ...contact })); + yield put(contactsActions.responseContactUpdate({ rosterId, payload: contact })); + yield put(searchListActions.updateContact({ id: rosterId, ...contact })); + + if (allOthernotifications && shouldNotify) { + const body = `${contact.names} ${contact.surnames} accepted your contact request! Send a message!`; + const type = notificationTypes.OTHER_NOTIFICATIONS; + const redirectLink = `/chats/${contactId}`; + showNotification(body, type, redirectLink); + } } + if (contactRequest) { - // console.log('handle contactRequest', contactRequest.payload); - // console.log('handle contactRequest phone_id', contactRequest.payload._data.phone_id); yield put(userListActions.settingsUpdate({ id: rosterId, phoneId: contactRequest.payload._data.phone_id, ...contactRequest.payload._data })); yield put(contactsActions.responseContactUpdate({ rosterId, payload: contactRequest.payload._data })); yield put(searchListActions.updateContact({ id: rosterId, ...contactRequest.payload._data })); @@ -365,16 +395,16 @@ function* handleContactUpdate() { yield delay(3000); yield put(closeMessageModal()); } + if (banned) { - // console.log('handle ContactBanned', banned); yield put(userListActions.settingsUpdate({ id: rosterId, phoneId: banned.payload._data.phone_id, ...banned.payload._data })); yield put(contactsActions.responseContactUpdate({ rosterId, payload: banned.payload._data })); yield put(openMessageModal('Contact blocked')); yield delay(3000); yield put(closeMessageModal()); } + if (ignoreContact) { - // console.log('handle ignoreContact', ignoreContact); yield put(userListActions.settingsUpdate({ id: rosterId, phoneId: ignoreContact.payload._data.phone_id, ...ignoreContact.payload._data })); yield put(contactsActions.responseContactUpdate({ rosterId, payload: ignoreContact.payload._data })); yield put(searchListActions.updateContact({ id: rosterId, ...ignoreContact.payload._data })); @@ -382,12 +412,12 @@ function* handleContactUpdate() { yield delay(3000); yield put(closeMessageModal()); } + if (searchByUsername) { - // console.log('handle searchByUsername', searchByUsername); yield put(searchListActions.update({ id: rosterId, ...searchByUsername.payload })); } + if (searchByNumber) { - // console.log('handle searchByNumber', searchByNumber); yield put(searchListActions.update({ id: rosterId, ...searchByNumber.payload })); } } -- GitLab From 49313f5da702991f32de208c58e37f5b602625ca Mon Sep 17 00:00:00 2001 From: JelianRadoev Date: Thu, 16 May 2019 15:20:59 +0300 Subject: [PATCH 33/33] Notifications settings hide sound option --- src/layouts/Notifications/Notifications.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/layouts/Notifications/Notifications.js b/src/layouts/Notifications/Notifications.js index b406d207d..4a1e25eeb 100644 --- a/src/layouts/Notifications/Notifications.js +++ b/src/layouts/Notifications/Notifications.js @@ -107,7 +107,7 @@ export class Notifications extends Component {
-
+ {/*
{translate('appSounds')}
-
+
*/} {/* Message notifications */}

{translate('messageNotifications')}

-- GitLab