From 94ca53f6caf5b354e48aa802101d1e668695ebae Mon Sep 17 00:00:00 2001 From: lockbitchat Date: Tue, 19 Aug 2025 21:54:17 -0400 Subject: [PATCH] Improve chat UI for secure channel creation pages Fix iOS PWA installation and improve cross-platform compatibility - Fix manifest.json paths (use relative paths with ./ for iOS) - Update Apple Touch Icons structure to use organized folders - Add missing 180x180px icon requirement for iOS - Fix apple-mobile-web-app meta tags configuration - Add viewport-fit=cover for iPhone X+ notch support - Fix missing showInstallButton() method causing TypeError - Add complete showInstallBanner() and createInstallBanner() methods - Implement proper hideInstallPrompts() functionality - Add iOS-specific installation instructions modal - Fix event handling for install prompt dismissal - Restructure PWA icons into platform-specific folders: - ./logo/pwa/ios/ for Apple Touch Icons - ./logo/pwa/android/ for Android launcher icons - ./logo/pwa/windows11/ for Microsoft Tiles - Update manifest.json to reference correct icon paths - Add browserconfig.xml for Windows 11 tile configuration - Improve PWA registration script without conflicts - Add proper error handling for offline functionality - Integrate with existing PWA modules (install prompt, offline manager) - Add update notifications for new app versions - Enhanced detection for iOS Safari vs other browsers - Improved installation flow for different platforms - Better user feedback for unsupported installation methods - Added fallback instructions for manual installation - Add comprehensive PWA support detection - Implement proper iOS standalone mode detection - Add console logging for installation status tracking - Include developer utilities for PWA management Tested on: iOS Safari, Chrome, Edge, Firefox Resolves iOS PWA installation issues and improves overall PWA experience." --- SECURITY_DISCLAIMER.md | 4 +- index.html | 349 +++++++++++++++------- logo/icon-128x128.png | Bin 0 -> 3021 bytes logo/icon-152x152.png | Bin 0 -> 3621 bytes logo/icon-180x180.png | Bin 0 -> 4282 bytes logo/icon-192x192.png | Bin 0 -> 4629 bytes logo/icon-256x256.png | Bin 0 -> 6215 bytes logo/icon-384x384.png | Bin 0 -> 6215 bytes logo/icon-512x512.png | Bin 0 -> 13349 bytes logo/icon-72x72.png | Bin 0 -> 1789 bytes logo/icon-96x96.png | Bin 0 -> 2409 bytes manifest.json | 111 ++++--- src/components/ui/Header.jsx | 2 +- src/components/ui/SessionTypeSelector.jsx | 7 +- src/pwa/install-prompt.js | 234 ++++++++++----- src/pwa/pwa-manager.js | 2 +- src/styles/components.css | 4 +- sw.js | 4 +- 18 files changed, 460 insertions(+), 257 deletions(-) create mode 100644 logo/icon-128x128.png create mode 100644 logo/icon-152x152.png create mode 100644 logo/icon-180x180.png create mode 100644 logo/icon-192x192.png create mode 100644 logo/icon-256x256.png create mode 100644 logo/icon-384x384.png create mode 100644 logo/icon-512x512.png create mode 100644 logo/icon-72x72.png create mode 100644 logo/icon-96x96.png diff --git a/SECURITY_DISCLAIMER.md b/SECURITY_DISCLAIMER.md index 77cddc5..6601c86 100644 --- a/SECURITY_DISCLAIMER.md +++ b/SECURITY_DISCLAIMER.md @@ -1,6 +1,6 @@ # Security Disclaimer and Terms of Use -## 🔒 SecureBit.chat Enhanced Security Edition v4.01.212 +## 🔒 SecureBit.chat Enhanced Security Edition v4.01.222 ### Important Legal Notice @@ -203,6 +203,6 @@ This software is created to: --- *Last Updated: 08.07.2025* -*Version: Enhanced Security Edition v4.01.212* +*Version: Enhanced Security Edition v4.01.222* **USE AT YOUR OWN RISK AND RESPONSIBILITY** \ No newline at end of file diff --git a/index.html b/index.html index 394fee8..414e062 100644 --- a/index.html +++ b/index.html @@ -24,45 +24,43 @@ + - - - - - - - + + + + + + - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - + + + + + + @@ -163,7 +161,7 @@ icon: "fas fa-shield-halved", color: "orange", title: "12-Layer Military Security", - description: "Revolutionary defense system with ECDH P-384 + AES-GCM 256 + ECDSA. Enhanced Security Edition v4.01.212 provides military-grade protection exceeding government standards." + description: "Revolutionary defense system with ECDH P-384 + AES-GCM 256 + ECDSA. Enhanced Security Edition v4.01.222 provides military-grade protection exceeding government standards." }, { icon: "fas fa-bolt", @@ -513,7 +511,7 @@ Enhanced Security Edition Comparison

- SecureBit.chat v4.01.212 Enhanced Security Edition vs leading secure messengers + SecureBit.chat v4.01.222 Enhanced Security Edition vs leading secure messengers

🏆 @@ -659,7 +657,7 @@

- SecureBit.chat v4.01.212 Enhanced Security Edition Summary + SecureBit.chat v4.01.222 Enhanced Security Edition Summary

SecureBit.chat dominates in 11 out of 15 security categories, establishing itself as the most secure P2P messenger available. @@ -2004,7 +2002,7 @@ React.createElement('i', { className: 'fas fa-check-circle mr-2' }), - 'Encrypted invitation created! Send the code and password to your contact.:' + 'Encrypted invitation created! Send the code and password to your contact:' ]), offerPassword && React.createElement('div', { key: 'password-display', @@ -2051,63 +2049,63 @@ ]), // Step 2 - Session Type Selection + // showOfferStep && React.createElement('div', { + // key: 'step2', + // className: "card-minimal rounded-xl p-6" + // }, [ + // React.createElement('div', { + // key: 'step-header', + // className: "flex items-center mb-4" + // }, [ + // React.createElement('div', { + // key: 'number', + // className: "w-8 h-8 bg-green-500 text-white rounded-lg flex items-center justify-center font-semibold text-sm mr-3" + // }, '2'), + // React.createElement('h3', { + // key: 'title', + // className: "text-lg font-medium text-primary" + // }, "Select session type") + // ]), + // React.createElement('p', { + // key: 'description', + // className: "text-secondary text-sm mb-4" + // }, "Choose a session plan or use limited demo mode for testing."), + // React.createElement(SessionTypeSelector, { + // key: 'session-selector', + // onSelectType: (sessionType) => { + // // Save the selected session type + // setSelectedSessionType(sessionType); + // console.log('🎯 Session type selected:', sessionType); + + // // FIX: For demo sessions, we immediately call automatic activation + // if (sessionType === 'demo') { + // console.log('🎮 Demo session selected, scheduling automatic activation...'); + // // Delay activation for 2 seconds to stabilize + // setTimeout(() => { + // if (sessionManager) { + // console.log('🚀 Triggering demo session activation from selection...'); + // handleDemoVerification(); + // } + // }, 2000); + // } + + // // Open a modal payment window + // if (typeof window.showPaymentModal === 'function') { + // window.showPaymentModal(sessionType); + // } else { + // // Fallback - show session information + // console.log('Selected session type:', sessionType); + // } + // }, + // onCancel: resetToSelect, + // sessionManager: window.sessionManager + // }) + // ]), + + // Step 3 - Waiting for response showOfferStep && React.createElement('div', { key: 'step2', className: "card-minimal rounded-xl p-6" - }, [ - React.createElement('div', { - key: 'step-header', - className: "flex items-center mb-4" - }, [ - React.createElement('div', { - key: 'number', - className: "w-8 h-8 bg-green-500 text-white rounded-lg flex items-center justify-center font-semibold text-sm mr-3" - }, '2'), - React.createElement('h3', { - key: 'title', - className: "text-lg font-medium text-primary" - }, "Select session type") - ]), - React.createElement('p', { - key: 'description', - className: "text-secondary text-sm mb-4" - }, "Choose a session plan or use limited demo mode for testing."), - React.createElement(SessionTypeSelector, { - key: 'session-selector', - onSelectType: (sessionType) => { - // Save the selected session type - setSelectedSessionType(sessionType); - console.log('🎯 Session type selected:', sessionType); - - // FIX: For demo sessions, we immediately call automatic activation - if (sessionType === 'demo') { - console.log('🎮 Demo session selected, scheduling automatic activation...'); - // Delay activation for 2 seconds to stabilize - setTimeout(() => { - if (sessionManager) { - console.log('🚀 Triggering demo session activation from selection...'); - handleDemoVerification(); - } - }, 2000); - } - - // Open a modal payment window - if (typeof window.showPaymentModal === 'function') { - window.showPaymentModal(sessionType); - } else { - // Fallback - show session information - console.log('Selected session type:', sessionType); - } - }, - onCancel: resetToSelect, - sessionManager: window.sessionManager - }) - ]), - - // Step 3 - Waiting for response - showOfferStep && React.createElement('div', { - key: 'step3', - className: "card-minimal rounded-xl p-6" }, [ React.createElement('div', { key: 'step-header', @@ -2116,7 +2114,7 @@ React.createElement('div', { key: 'number', className: "w-8 h-8 bg-blue-500 text-white rounded-lg flex items-center justify-center font-semibold text-sm mr-3" - }, '3'), + }, '2'), React.createElement('h3', { key: 'title', className: "text-lg font-medium text-primary" @@ -3794,36 +3792,175 @@ console.log('✅ Global timer management functions loaded'); \ No newline at end of file diff --git a/logo/icon-128x128.png b/logo/icon-128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..24bd86cd2c644d88a228e5c35cc419d29ec777bb GIT binary patch literal 3021 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 literal 0 HcmV?d00001 diff --git a/logo/icon-180x180.png b/logo/icon-180x180.png new file mode 100644 index 0000000000000000000000000000000000000000..ec3d50eb6b384a84aa603a68506817c92eb4a012 GIT binary patch literal 4282 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 Aj{pDw literal 0 HcmV?d00001 diff --git a/logo/icon-192x192.png b/logo/icon-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..d985d80b3cf41632f1b58e37692b7f7c43a30890 GIT binary patch literal 4629 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%0A;vm9 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ö_oKX|fvSDwk+~e9NzClA!EtEnh)LNwEP%nR{WnV?=Zy zSZYVwIo!})^o{+WPqU>q(bmCJ(QO_tg}E<4Ta+}4Mp`bY}q6pWI_e|oP%H+oLST}-BByc2uqQEP zT_QF8o!XC7tBI4nHy3C;J$N3K2~*}MW&bWg9-5sMMR#LPShyxI{{Rz&T+BBk`a^c( zUuT}9-82Ui6JnVY*H8(R{g|rV%WA&23~bz4SBHj{;F?b=mwh7K2g+QKu<-^b4O!wT z>wOTtApTuIfLiZ)cz{Ea?olqPxs+_*K&3({5O+&;>^D)cdS3w`y8aB)gB_3#LMI(Mi4qe1$OY!=%LoXWInGyh^k zT@p_>KLpTHqa^%Y)%7` zTpjn47+J&f(T|4wBAIsZXE{Y9=g9Uy$3b~p83`cXSxaLiw$@|7V@TnMbY=6ocM|u&3?(GFAQ>NvS z_1ztG7~Rom#UTZAH^JE)OP9p6qm_fB$DwsZqT)0b0=tEQy=JW)QC}~?UjORZ_OIDw zZGG>0VNEy%G9ng4Z-*S&^u*D`NbkjMC+$`F#I=elBWw~Wn1di;^yTF*2cFjcUh6t| zsUO_`9Y-%ifW2y`6#aJ!FC-R_99UT?dO{tPY#FH`Xn)t4N&AUv&%O_PNJkHYPTx%);+T9E)k{?3go|d~=;q<_p+lkhqr{v@5LQZZJ+MBon@3M?Og$fR zoIyQUwA4XsK{Rox+CfBG>&fetPl&?s4CLAx?#v-87~9X?Lu*ljXPgNjtd);R`s~}+ zK9VCnNp#ZsQBJt4rY@3D^PPIk;aeYKSrWAk*T*gHCEy5)|Dh+twVcL)t9dytx|!y` zzq};78KFQN!d6@0`d-CQj@L^fmgCUn8}WsGEP`BJq{#m*e+??2_j+)!$ir-Vc}tSJ zQ;3W3=>bfPKEwO#{Kg;;?AX)XQWXM_xrtI^f1YW0zJjq5y(ldkRUzB;swI<11?{*U zEp0<4Fx)^#N9Qy{R*atY?LwgLZ6ckbo>PuODjg#xHg`koim6NF$ir6En(@hL_J}}p z1&4e$vfgL0KOZ6D?K@%5%!8$Qe)Ql^8+w56uQPd0BUwl>RpP_wXaVc=Nj}Xuw`^W| zfwnv|qc^PbPd%UM$v}WH)XkEjv=H}5Rv726rb@;#!G_(WHuZF@96h)Pe(@a#{r?HF{|~}mcSV67dn3i3`MZI5GXQ8k)K#mwZx!)B D!*zao literal 0 HcmV?d00001 diff --git a/logo/icon-384x384.png b/logo/icon-384x384.png new file mode 100644 index 0000000000000000000000000000000000000000..84fee807c9370ae90ca441779130f6673fa8ee95 GIT binary patch literal 6215 zcmd6s=T}orw8l>eoq$vc9R;K}5fCW}iWHHqfGE96??ggJAT$F=limcRqx9ZU5Tnw2 z02M+nf;j?u%2nDsXjsE>?~5GKAr3&-}eY?4+t!VaFOB+ z)$}V=>%$6Wif*dCl8(KFF=dQBzY{AVkmV3-U|>T_Zu=0V3Qyiek(SVMm11&RWqkG) zKJ0BrRuzzZgM8XkM(*u3PdyWL8I%?B`PPgN)oAiq?xIq&E77D+u7?6@yEmwu;|NSEZ>Sz<`|2h3f!E7cYJLd&Q+CvSAVF5^^Aed_d!L97h{i!<<6GMQ$>Awc23nx>?QZw6&)ADh*z3eh0Z~i|C z+JigmrPyk>r@Y2+Ll`)2Q|8mENg7;BzY!pkroZh}P<4 z+_vv1q>Wwj6SM<|`9%6=7cZtB>7jbu_}(78 zWzagcD!XcyO5Z%EViNwfY)YNUd+ zK4wK#ND7D$8)b>zs;(zAf)_R8r;D?f&4Oi$4>lgMwKxW`TQo;g9LYb$qB8m;t!x0& zFSEI;o@>uyGiOAX+{tj=DYpFwYoFdqArXu!b36U<#`IN7!z-#%QUE{Ws6X-aN%x=c z$2`Q7kUE4+yG`4-XWCjx)V-I+$^r*5S z_$?b7U?X|?u#;(<^+f~SUvnGDF2q2M`oTZnNqBRoqb0@aKS>d>SVwKuo+bO!Z%rZ- z?51@CVYt845DrvOvZS%sU>a zaOJCYOWn_)w!BnC&E(bY$nEw<=E+2N&MXvYHt_2Ql*^CZ{G@0ajAoCU2Ww%0A;vm9 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ö_oKX|fvSDwk+~e9NzClA!EtEnh)LNwEP%nR{WnV?=Zy zSZYVwIo!})^o{+WPqU>q(bmCJ(QO_tg}E<4Ta+}4Mp`bY}q6pWI_e|oP%H+oLST}-BByc2uqQEP zT_QF8o!XC7tBI4nHy3C;J$N3K2~*}MW&bWg9-5sMMR#LPShyxI{{Rz&T+BBk`a^c( zUuT}9-82Ui6JnVY*H8(R{g|rV%WA&23~bz4SBHj{;F?b=mwh7K2g+QKu<-^b4O!wT z>wOTtApTuIfLiZ)cz{Ea?olqPxs+_*K&3({5O+&;>^D)cdS3w`y8aB)gB_3#LMI(Mi4qe1$OY!=%LoXWInGyh^k zT@p_>KLpTHqa^%Y)%7` zTpjn47+J&f(T|4wBAIsZXE{Y9=g9Uy$3b~p83`cXSxaLiw$@|7V@TnMbY=6ocM|u&3?(GFAQ>NvS z_1ztG7~Rom#UTZAH^JE)OP9p6qm_fB$DwsZqT)0b0=tEQy=JW)QC}~?UjORZ_OIDw zZGG>0VNEy%G9ng4Z-*S&^u*D`NbkjMC+$`F#I=elBWw~Wn1di;^yTF*2cFjcUh6t| zsUO_`9Y-%ifW2y`6#aJ!FC-R_99UT?dO{tPY#FH`Xn)t4N&AUv&%O_PNJkHYPTx%);+T9E)k{?3go|d~=;q<_p+lkhqr{v@5LQZZJ+MBon@3M?Og$fR zoIyQUwA4XsK{Rox+CfBG>&fetPl&?s4CLAx?#v-87~9X?Lu*ljXPgNjtd);R`s~}+ zK9VCnNp#ZsQBJt4rY@3D^PPIk;aeYKSrWAk*T*gHCEy5)|Dh+twVcL)t9dytx|!y` zzq};78KFQN!d6@0`d-CQj@L^fmgCUn8}WsGEP`BJq{#m*e+??2_j+)!$ir-Vc}tSJ zQ;3W3=>bfPKEwO#{Kg;;?AX)XQWXM_xrtI^f1YW0zJjq5y(ldkRUzB;swI<11?{*U zEp0<4Fx)^#N9Qy{R*atY?LwgLZ6ckbo>PuODjg#xHg`koim6NF$ir6En(@hL_J}}p z1&4e$vfgL0KOZ6D?K@%5%!8$Qe)Ql^8+w56uQPd0BUwl>RpP_wXaVc=Nj}Xuw`^W| zfwnv|qc^PbPd%UM$v}WH)XkEjv=H}5Rv726rb@;#!G_(WHuZF@96h)Pe(@a#{r?HF{|~}mcSV67dn3i3`MZI5GXQ8k)K#mwZx!)B D!*zao literal 0 HcmV?d00001 diff --git a/logo/icon-512x512.png b/logo/icon-512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..8c4b6d027feb4ba7123d332123c71f082a1d19b9 GIT binary patch literal 13349 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�vAf)fAF4ah*C)UG$tsY|9Eq2*W3luxD+b1jJ9S%UAL30BypNxhZf3?k zrw?EM=E65uoM`pR=YFyXl$k`_=*c)dmt}!bFU^g{e^iV7F;*QuoX6dY{8**hJg?m?75qlxJkElh<{G`M}(cBX|HFO0KdC2?oI?nfWs=j1`o+f$D! zN0;DhixTMF83_m%bPGa9cAAl_lJS_684W{Za4R+ukqUEdSb5-q;Ohw%C?+a`xR-o$ zj##eLcVTsX12&)5V=-Co>0Fg!iDW%~HVHeTh>+dA!a@PT0u4_vKut7xeAscml^M@u zT2MgTFK3`J;IWy+Ew9}d=4OHg(no}DQkF_dm75vWg&D+J{{OjA&wqmNN3cNMKJ^!3 zqgXtxvqyOPM6f`vuJGq*f{_r-J`c5bDj-mcSKR_7#jp$1=n=jJ5n(~S@b>s&HmGwh z8fFh1A5rV^D&b<3y7nH7O60#!Qj+2Jz^iOsn@`mFLw{z_Nxi@Rr00$u*I6KW(_+NJ!S zxO)~Q5M2?d$qGqmDZy+Ow=b*fWb#a65SI4r^3BfLIT$!v%saBvKn6B-h1u zUv^<@Uifm%A!`_Y?j%*(PMl+da!EqSxC<3gLH z!0^Aw>JyuOY-V=U!4l_E7?BW#y^990ZYgNUA=li~kE{aGzMKu;H{;X%WXKKeR4ZPZ z#=2Vi`uuq7n0&6)kL$yJEuP>{!{(Icr2TKA4k&SQC4pU`uI>tgh8hNS2-T zC!3IAH(=rr={5WfGZXOI_~2QC{nuRh@{;tRFc2YImkSO$7?&8GB(9d9m2AX^bCd80 z$2R5^Ssd1uG$K@lOdwi6Td?;YiWa6JdjS8v8trpjGu4JAWPiog2XL&?gEimDKkqzD zNFzIEXCD^rtH&q#DVUML&)v?i8qB&%J?O__w-<%W=i}BxX=j!s~{c|nYQ|=7OD+YWC>-%D~q4LwRHs%$A{4p^| z{Cf}A)X|G06>e2DYpLRmLpO<;iioAC5mgAJW;B5~&;;T@6Nm#%APzKvIM4**Kof`q fO&|_5fjIaJldv90jg9d800000NkvXXu0mjf^>S2d literal 0 HcmV?d00001 diff --git a/logo/icon-96x96.png b/logo/icon-96x96.png new file mode 100644 index 0000000000000000000000000000000000000000..1a909bf6eda6934c4169c67254513850caac76b9 GIT binary patch literal 2409 zcmai$=Q|sU0>(Lnn2iy%RuY_At!j*eqOoENRh8CgY?qWO)e?G7jG|3SD{8Be*s1Ly zB(;yCRf3{D_6RlGn!)Y)dhdt(;rG7J^S=MUFBxTz6ym?Y&%wbVWMygQ^s9aT0m$4(!VxoD>H=iquh-=fl%iqaNij;XTtB**C7LhsdyK> zjbI0J!p0yt)x!7qryS=pFkuA61g>MdiRh(&$-rPI&+q}Z1I~l!ymbaC=g0By z;ibn^%SH&fe^ypso@GIvb4Meb)cFq96s0rxp%igN$>oj$NmQzK8v;y1KkCW>OQ3Px_t;@fzHpn&zU`h$=#%oD-gb z;87>a0bHn96e2_e{mhy8TwC;o_*EWIv-3uhW)B#i`8e<|SKvz(dX+&b-^EKXidycJ zk!Uh54wOT+a5xvML8&+9A7BaY{mG>X_A$A4b+cuPI`}itN^}TnZ7pNZBYyiVq`p|5LDt-|?ybLN_PV|lA4AqA(S zS@-aZlj<<1_uZm9BYLdl)c&~#7^OwhPP9M4UgVZs?Di7y6t#5&*5Ja34Z1J{C|9<> zQT1n)iQ2>1;ROHvs8E~oo9I$!@fTlqEx$aika0z0`iT3qog$FmOdn?e!4I#lT95H1 ziILG(!xwgq+S6ivvkQZQo3`y>K6G#E-lUk(cj7h^<=+h--77%y6*QW(LV7wKPs2Tk zUgvA)yY{Zo8C`@3nnCEX&)i$HS%~*tw=DCmjLIs4%S2;gx#?+?MFqq>OM>~gdps`3 zOp5J?Ja-F5lMn zl=3^U+oItzWIvt_C~O>-@YPj}2rD3ho=*^uNkMKO5&&yO{idF8j8LrEi$HU2R)3cR zM{oB2SIjkfwUEPx{);sg9d$5$x#HVuRi0>p(g#H?>#%JnZk79WmdOMu{@--kR&G)& zG$qF!bP4rPO-!h~rcO>4M2G86-^vaZ$g!I3ve@JK8Y~p`R^g@xM8P~YANW?h$=1Yh z4Lutgk4^`FBX}Z4UNWnVhr4V+AxV86cnPytH9xo&MvNR%Ao=gknjx~HGoC4sjjy{F zKwW+~lL5<8LcUa2EIJUGT20oaqWX>Edt86;WTAnd7Fit!xvTHPpT|$ho%KI#xkDe} z4&3|EONJ~s|IP9~HyRugXYgG5Z5=FM8SGV3X4}>04lOTGu}fW`es&28=vZWnk3|z3 zujbYH7)$Z0ri=mf!iePw!%gL$>L9Gj&Z~*m<=u|v!s*td(D6RzQ_yjC-2DaQZg8?x zrRXkwntAEu0hvE+Hk=K-8rf#|Gyi00_l3SC*vFxGFTy73{)6(PcTvc=eUd6LuV+;mpcz$^RU1LvRrrz!L zY*QWP5laPg-iCs_$kWKj9?*=DIqX?gwJZQiGa7pmTB9x2V{u1W36EX>&}`k4V;U^g z>V8QAwECY-b^o?bzvW)mP7CekJt&4={EGiM2FP@ga=(rsvG>RG&8w2E^!HFUsPlgs zAEz`GZkM!)S22obpXk4?xIdHO(s1M**#`4F+!=ZrlX*L{sNwr7f|4d@rP=oOU6Qw@ zi{*)puvTAF*zXi+2_~dhRU%-_cUPzW_hqF8*5Tt${luo_!!%%sim7an7d@`wD5QFu z=cuL#caULnp5m4R2%=|_lMKWs%vj|}^G5>+LD(`LWQ-fAmdSN998_GaUckDd=TL_F zp(>j*Yn@FzSnH@nE&)W6|6aHF=b(^twW`mHnpXTCBkbdl25@ z-cO1IuJ{WPx#9yw<7Rh$>? zjvjqTwh1qIofvzX2)F*@cssasWJ2?H*|XKi=9Y-SEmeU%JV*p{iCGY{uF0sY^Srqv z^W%x_8&>kw0gZ{{^a5?sM34_hShw?SGjc9dV}~*l?sn@XrD3U|LcL;wH) literal 0 HcmV?d00001 diff --git a/manifest.json b/manifest.json index f93c160..c91429b 100644 --- a/manifest.json +++ b/manifest.json @@ -2,65 +2,88 @@ "name": "SecureBit.chat - Enhanced Security Edition", "short_name": "SecureBit", "description": "P2P messenger with military-grade cryptography and Lightning Network payments", - "start_url": "/", + "start_url": "./", "display": "standalone", "background_color": "#1a1a1a", "theme_color": "#ff6b35", "orientation": "portrait-primary", - "scope": "/", + "scope": "./", "lang": "en", "dir": "ltr", "categories": ["communication", "security", "productivity"], - "iarc_rating_id": "", "prefer_related_applications": false, "icons": [ { - "src": "logo/icon-72x72.png", + "src": "./logo/icon-72x72.png", "sizes": "72x72", "type": "image/png", - "purpose": "maskable any" + "purpose": "any" }, { - "src": "logo/icon-96x96.png", + "src": "./logo/icon-96x96.png", "sizes": "96x96", "type": "image/png", - "purpose": "maskable any" + "purpose": "any" }, { - "src": "logo/icon-128x128.png", + "src": "./logo/icon-128x128.png", "sizes": "128x128", "type": "image/png", - "purpose": "maskable any" + "purpose": "any" }, { - "src": "logo/icon-144x144.png", + "src": "./logo/icon-144x144.png", "sizes": "144x144", "type": "image/png", - "purpose": "maskable any" + "purpose": "any" }, { - "src": "logo/icon-152x152.png", + "src": "./logo/icon-152x152.png", "sizes": "152x152", "type": "image/png", - "purpose": "maskable any" + "purpose": "any" }, { - "src": "logo/icon-192x192.png", + "src": "./logo/icon-180x180.png", + "sizes": "180x180", + "type": "image/png", + "purpose": "any" + }, + { + "src": "./logo/icon-192x192.png", "sizes": "192x192", "type": "image/png", - "purpose": "maskable any" + "purpose": "any" }, { - "src": "logo/icon-384x384.png", + "src": "./logo/icon-256x256.png", + "sizes": "256x256", + "type": "image/png", + "purpose": "any" + }, + { + "src": "./logo/icon-384x384.png", "sizes": "384x384", "type": "image/png", - "purpose": "maskable any" + "purpose": "any" }, { - "src": "logo/icon-512x512.png", + "src": "./logo/icon-512x512.png", "sizes": "512x512", "type": "image/png", - "purpose": "maskable any" + "purpose": "any" + }, + { + "src": "./logo/icon-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "./logo/icon-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" } ], "shortcuts": [ @@ -68,57 +91,27 @@ "name": "Create Channel", "short_name": "Create", "description": "Create a new secure channel", - "url": "/?action=create", + "url": "./?action=create", "icons": [ { - "src": "logo/icon-96x96.png", - "sizes": "96x96" + "src": "./logo/icon-96x96.png", + "sizes": "96x96", + "type": "image/png" } ] }, { "name": "Join Channel", - "short_name": "Join", + "short_name": "Join", "description": "Join an existing secure channel", - "url": "/?action=join", + "url": "./?action=join", "icons": [ { - "src": "logo/icon-96x96.png", - "sizes": "96x96" + "src": "./logo/icon-96x96.png", + "sizes": "96x96", + "type": "image/png" } ] } - ], - "screenshots": [ - { - "src": "screenshots/desktop-1.png", - "sizes": "1280x720", - "type": "image/png", - "form_factor": "wide", - "label": "SecureBit.chat main interface" - }, - { - "src": "screenshots/mobile-1.png", - "sizes": "414x896", - "type": "image/png", - "form_factor": "narrow", - "label": "SecureBit.chat mobile interface" - } - ], - "related_applications": [], - "protocol_handlers": [ - { - "protocol": "web+securebit", - "url": "/?invite=%s" - } - ], - "share_target": { - "action": "/share", - "method": "GET", - "params": { - "title": "title", - "text": "text", - "url": "url" - } - } + ] } \ No newline at end of file diff --git a/src/components/ui/Header.jsx b/src/components/ui/Header.jsx index 8f74e3b..35568e8 100644 --- a/src/components/ui/Header.jsx +++ b/src/components/ui/Header.jsx @@ -497,7 +497,7 @@ const EnhancedMinimalHeader = ({ React.createElement('p', { key: 'subtitle', className: 'text-xs sm:text-sm text-muted hidden sm:block' - }, 'End-to-end freedom. v4.01.212') + }, 'End-to-end freedom. v4.01.222') ]) ]), diff --git a/src/components/ui/SessionTypeSelector.jsx b/src/components/ui/SessionTypeSelector.jsx index ffc323f..c371abe 100644 --- a/src/components/ui/SessionTypeSelector.jsx +++ b/src/components/ui/SessionTypeSelector.jsx @@ -374,12 +374,7 @@ const SessionTypeSelector = ({ onSelectType, onCancel, sessionManager }) => { onClick: onCancel, className: 'px-6 py-3 bg-gray-600 hover:bg-gray-500 text-white rounded-lg transition-all' }, 'Cancel'), - React.createElement('button', { - key: 'refresh', - onClick: updateDemoInfo, - className: 'px-3 py-3 bg-blue-600 hover:bg-blue-500 text-white rounded-lg transition-all', - title: 'Refresh demo status' - }, React.createElement('i', { className: 'fas fa-sync-alt' })) + ]) ]); }; diff --git a/src/pwa/install-prompt.js b/src/pwa/install-prompt.js index dd9353d..ac903ee 100644 --- a/src/pwa/install-prompt.js +++ b/src/pwa/install-prompt.js @@ -1,6 +1,3 @@ -// PWA Install Prompt Manager for SecureBit.chat -// Enhanced Security Edition v4.01.212 - class PWAInstallPrompt { constructor() { this.deferredPrompt = null; @@ -21,11 +18,16 @@ class PWAInstallPrompt { this.createInstallButton(); this.loadInstallPreferences(); + if (this.isIOSSafari() && !this.isInstalled && this.shouldShowPrompt()) { + setTimeout(() => { + this.showIOSInstallInstructions(); + }, 3000); + } + console.log('✅ PWA Install Prompt initialized'); } checkInstallationStatus() { - // Check if app is already installed if (window.matchMedia('(display-mode: standalone)').matches || window.navigator.standalone === true) { this.isInstalled = true; @@ -34,17 +36,24 @@ class PWAInstallPrompt { return true; } - // Check for iOS Safari specific installation if (this.isIOSSafari()) { this.isInstalled = window.navigator.standalone === true; + if (this.isInstalled) { + console.log('📱 iOS PWA detected'); + document.body.classList.add('pwa-installed', 'ios-pwa'); + } } document.body.classList.add(this.isInstalled ? 'pwa-installed' : 'pwa-browser'); + + if (this.isIOSSafari()) { + document.body.classList.add('ios-safari'); + } + return this.isInstalled; } setupEventListeners() { - // Capture the install prompt event window.addEventListener('beforeinstallprompt', (event) => { console.log('💿 Install prompt event captured'); event.preventDefault(); @@ -55,7 +64,6 @@ class PWAInstallPrompt { } }); - // Handle successful installation window.addEventListener('appinstalled', () => { console.log('✅ PWA installed successfully'); this.isInstalled = true; @@ -63,35 +71,45 @@ class PWAInstallPrompt { this.showInstallSuccess(); this.saveInstallPreference('installed', true); - // Update UI for installed state document.body.classList.remove('pwa-browser'); document.body.classList.add('pwa-installed'); }); - // Handle iOS installation detection if (this.isIOSSafari()) { + let wasStandalone = window.navigator.standalone; + window.addEventListener('visibilitychange', () => { if (document.hidden) return; setTimeout(() => { - if (window.navigator.standalone && !this.isInstalled) { + const isStandalone = window.navigator.standalone; + + if (isStandalone && !wasStandalone && !this.isInstalled) { + console.log('✅ iOS PWA installation detected'); this.isInstalled = true; this.hideInstallPrompts(); this.showInstallSuccess(); + document.body.classList.remove('pwa-browser'); + document.body.classList.add('pwa-installed', 'ios-pwa'); } + + wasStandalone = isStandalone; }, 1000); }); } } createInstallButton() { - // Create floating install button this.installButton = document.createElement('button'); this.installButton.id = 'pwa-install-button'; this.installButton.className = 'hidden fixed bottom-6 right-6 bg-gradient-to-r from-orange-500 to-orange-600 hover:from-orange-600 hover:to-orange-700 text-white px-6 py-3 rounded-full shadow-lg transition-all duration-300 z-50 flex items-center space-x-3 group'; + + const buttonText = this.isIOSSafari() ? 'Install App' : 'Install App'; + const buttonIcon = this.isIOSSafari() ? 'fas fa-share' : 'fas fa-download'; + this.installButton.innerHTML = ` - - Install App + + ${buttonText}

`; @@ -109,23 +127,27 @@ class PWAInstallPrompt { this.installBanner.id = 'pwa-install-banner'; this.installBanner.className = 'pwa-install-banner fixed bottom-0 left-0 right-0 transform translate-y-full transition-transform duration-300 z-40'; this.installBanner.innerHTML = ` -
-
- +
+
+
+
+ +
+
+
Install SecureBit.chat
+
Get the native app experience with enhanced security
+
+
+
+ + +
-
-
Install SecureBit.chat
-
Get the native app experience with enhanced security
-
-
-
- -
`; @@ -146,11 +168,11 @@ class PWAInstallPrompt { showInstallOptions() { if (this.isInstalled) return; - // For mobile devices, show banner - if (this.isMobileDevice()) { + if (this.isIOSSafari()) { + this.showInstallButton(); + } else if (this.isMobileDevice()) { this.showInstallBanner(); } else { - // For desktop, show floating button this.showInstallButton(); } } @@ -179,6 +201,7 @@ class PWAInstallPrompt { if (this.installBanner && !this.isInstalled) { setTimeout(() => { this.installBanner.classList.add('show'); + this.installBanner.style.transform = 'translateY(0)'; }, 1000); console.log('💿 Install banner shown'); @@ -192,12 +215,13 @@ class PWAInstallPrompt { if (this.installBanner) { this.installBanner.classList.remove('show'); + this.installBanner.style.transform = 'translateY(100%)'; } } async handleInstallClick() { if (this.isIOSSafari()) { - this.showIOSInstructions(); + this.showIOSInstallInstructions(); return; } @@ -210,7 +234,6 @@ class PWAInstallPrompt { try { console.log('💿 Showing install prompt...'); - // Show the install prompt const result = await this.deferredPrompt.prompt(); console.log('💿 Install prompt result:', result.outcome); @@ -223,7 +246,6 @@ class PWAInstallPrompt { this.handleInstallDismissal(); } - // Clear the deferred prompt this.deferredPrompt = null; } catch (error) { @@ -232,42 +254,73 @@ class PWAInstallPrompt { } } - showIOSInstructions() { + showIOSInstallInstructions() { const modal = document.createElement('div'); - modal.className = 'fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4'; + modal.className = 'fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4 backdrop-blur-sm'; modal.innerHTML = `

Install on iOS

-
-
-
1
- Tap the Share button + +
+
+
1
+
+
Tap the Share button
+
+ + Usually at the bottom of Safari +
+
-
-
2
- Select "Add to Home Screen" + +
+
2
+
+
Find "Add to Home Screen"
+
Scroll down in the share menu
+
-
-
3
- Tap "Add" to install + +
+
3
+
+
Tap "Add"
+
Confirm to install SecureBit.chat
+
- + +
+

+ + After installation, open SecureBit from your home screen for the best experience. +

+
+ +
+ + +
`; document.body.appendChild(modal); + + this.saveInstallPreference('ios_instructions_shown', Date.now()); } showFallbackInstructions() { const modal = document.createElement('div'); - modal.className = 'fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4'; + modal.className = 'fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4 backdrop-blur-sm'; modal.innerHTML = `
@@ -307,6 +360,11 @@ class PWAInstallPrompt { showInstallSuccess() { const notification = document.createElement('div'); notification.className = 'fixed top-4 right-4 bg-green-500 text-white p-4 rounded-lg shadow-lg z-50 max-w-sm transform translate-x-full transition-transform duration-300'; + + const successText = this.isIOSSafari() ? + 'iOS App installed! Open from home screen.' : + 'SecureBit.chat is now on your device'; + notification.innerHTML = `
@@ -314,23 +372,51 @@ class PWAInstallPrompt {
App Installed!
-
SecureBit.chat is now on your device
+
${successText}
`; document.body.appendChild(notification); - // Animate in setTimeout(() => { notification.classList.remove('translate-x-full'); }, 100); - // Auto-remove after 4 seconds setTimeout(() => { notification.classList.add('translate-x-full'); setTimeout(() => notification.remove(), 300); - }, 4000); + }, 5000); + } + + shouldShowPrompt() { + const preferences = this.loadInstallPreferences(); + + if (this.isInstalled) return false; + + if (this.isIOSSafari()) { + const lastShown = preferences.ios_instructions_shown; + const lastDismissed = localStorage.getItem('ios_install_dismissed'); + + if (lastShown && Date.now() - lastShown < 24 * 60 * 60 * 1000) { + return false; + } + + if (lastDismissed && Date.now() - parseInt(lastDismissed) < 7 * 24 * 60 * 60 * 1000) { + return false; + } + + return true; + } + + if (preferences.dismissed >= this.maxDismissals) return false; + + const lastDismissed = preferences.lastDismissed; + if (lastDismissed && Date.now() - lastDismissed < 24 * 60 * 60 * 1000) { + return false; + } + + return true; } dismissInstallPrompt() { @@ -351,12 +437,11 @@ class PWAInstallPrompt { this.saveInstallPreference('dismissed', this.dismissedCount); if (this.dismissedCount < this.maxDismissals) { - // Show reminder after some time setTimeout(() => { if (!this.isInstalled && this.shouldShowPrompt()) { this.showInstallButton(); } - }, 300000); // 5 minutes + }, 300000); } } @@ -390,24 +475,6 @@ class PWAInstallPrompt { }, 10000); } - shouldShowPrompt() { - const preferences = this.loadInstallPreferences(); - - // Don't show if already installed - if (this.isInstalled) return false; - - // Don't show if dismissed too many times - if (preferences.dismissed >= this.maxDismissals) return false; - - // Don't show if recently dismissed (less than 24 hours) - const lastDismissed = preferences.lastDismissed; - if (lastDismissed && Date.now() - lastDismissed < 24 * 60 * 60 * 1000) { - return false; - } - - return true; - } - saveInstallPreference(action, value) { const preferences = this.loadInstallPreferences(); preferences[action] = value; @@ -439,12 +506,16 @@ class PWAInstallPrompt { isIOSSafari() { const userAgent = navigator.userAgent; - return /iPad|iPhone|iPod/.test(userAgent) && /Safari/.test(userAgent) && !/CriOS|FxiOS/.test(userAgent); + const isIOS = /iPad|iPhone|iPod/.test(userAgent); + const isSafari = /Safari/.test(userAgent) && !/CriOS|FxiOS|EdgiOS/.test(userAgent); + return isIOS && isSafari; } // Public API methods showInstallPrompt() { - if (this.deferredPrompt && !this.isInstalled) { + if (this.isIOSSafari()) { + this.showIOSInstallInstructions(); + } else if (this.deferredPrompt && !this.isInstalled) { this.handleInstallClick(); } else { this.showFallbackInstructions(); @@ -459,6 +530,7 @@ class PWAInstallPrompt { return { isInstalled: this.isInstalled, canPrompt: !!this.deferredPrompt, + isIOSSafari: this.isIOSSafari(), dismissedCount: this.dismissedCount, shouldShowPrompt: this.shouldShowPrompt() }; @@ -469,6 +541,12 @@ class PWAInstallPrompt { this.saveInstallPreference('dismissed', 0); console.log('💿 Install dismissals reset'); } + + // Method for setting service worker registration + setServiceWorkerRegistration(registration) { + this.swRegistration = registration; + console.log('📡 Service Worker registration set for PWA Install Prompt'); + } } // Export for module use diff --git a/src/pwa/pwa-manager.js b/src/pwa/pwa-manager.js index 85a9ea1..75a9d42 100644 --- a/src/pwa/pwa-manager.js +++ b/src/pwa/pwa-manager.js @@ -1,5 +1,5 @@ // PWA Offline Manager for SecureBit.chat -// Enhanced Security Edition v4.01.212 +// Enhanced Security Edition v4.01.222 // Handles offline functionality, data synchronization, and user experience class PWAOfflineManager { diff --git a/src/styles/components.css b/src/styles/components.css index e1f027a..7963a64 100644 --- a/src/styles/components.css +++ b/src/styles/components.css @@ -164,11 +164,11 @@ main { border: 1px solid rgba(75, 85, 99, 0.2); box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1); } -.card-minimal:hover { +/* .card-minimal:hover { border-color: rgba(249, 115, 22, 0.3); transform: translateY(-1px); transition: all 0.2s ease; -} +} */ .status-dot { width: 8px; diff --git a/sw.js b/sw.js index 1ecf01e..f64f5ff 100644 --- a/sw.js +++ b/sw.js @@ -1,5 +1,5 @@ // SecureBit.chat Service Worker -// Enhanced Security Edition v4.01.212 +// Enhanced Security Edition v4.01.222 const CACHE_NAME = 'securebit-v4.0.3'; const STATIC_CACHE = 'securebit-static-v4.0.3'; @@ -352,4 +352,4 @@ self.addEventListener('unhandledrejection', (event) => { console.error('❌ Service Worker unhandled rejection:', event.reason); }); -console.log('🔧 SecureBit.chat Service Worker loaded - Enhanced Security Edition v4.01.212'); \ No newline at end of file +console.log('🔧 SecureBit.chat Service Worker loaded - Enhanced Security Edition v4.01.222'); \ No newline at end of file