with image support
This commit is contained in:
		| @@ -1,160 +1,56 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | <!-- Generator: Adobe Illustrator 9.0, SVG Export Plug-In  --> | ||||||
|  |  | ||||||
| <svg | <svg | ||||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" |    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||||
|    xmlns:cc="http://web.resource.org/cc/" |    xmlns:cc="http://creativecommons.org/ns#" | ||||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||||
|    xmlns:svg="http://www.w3.org/2000/svg" |    xmlns:svg="http://www.w3.org/2000/svg" | ||||||
|    xmlns="http://www.w3.org/2000/svg" |    xmlns="http://www.w3.org/2000/svg" | ||||||
|    xmlns:xlink="http://www.w3.org/1999/xlink" |    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||||
|    xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd" |  | ||||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||||
|    width="48" |    width="48pt" | ||||||
|    height="48" |    height="48pt" | ||||||
|    id="svg79606" |    viewBox="0 0 48 48" | ||||||
|    sodipodi:version="0.32" |    xml:space="preserve" | ||||||
|    inkscape:version="0.42+devel" |    id="svg4573" | ||||||
|    version="1.0" |    version="1.1" | ||||||
|    sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/status" |    inkscape:version="0.48.4 r9939" | ||||||
|    sodipodi:docname="mail-attachment.svg"> |    sodipodi:docname="attachment.svg"><metadata | ||||||
|   <defs |      id="metadata4589"><rdf:RDF><cc:Work | ||||||
|      id="defs79608"> |          rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type | ||||||
|     <linearGradient |            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs | ||||||
|        id="linearGradient5783"> |      id="defs4587" /><sodipodi:namedview | ||||||
|       <stop |  | ||||||
|          style="stop-color:#d3d7cf;stop-opacity:1;" |  | ||||||
|          offset="0" |  | ||||||
|          id="stop5785" /> |  | ||||||
|       <stop |  | ||||||
|          id="stop5791" |  | ||||||
|          offset="0.5" |  | ||||||
|          style="stop-color:#f5f5f5;stop-opacity:1;" /> |  | ||||||
|       <stop |  | ||||||
|          style="stop-color:#bebebe;stop-opacity:1;" |  | ||||||
|          offset="1" |  | ||||||
|          id="stop5787" /> |  | ||||||
|     </linearGradient> |  | ||||||
|     <linearGradient |  | ||||||
|        inkscape:collect="always" |  | ||||||
|        id="linearGradient3558"> |  | ||||||
|       <stop |  | ||||||
|          style="stop-color:#000000;stop-opacity:1;" |  | ||||||
|          offset="0" |  | ||||||
|          id="stop3560" /> |  | ||||||
|       <stop |  | ||||||
|          style="stop-color:#000000;stop-opacity:0;" |  | ||||||
|          offset="1" |  | ||||||
|          id="stop3562" /> |  | ||||||
|     </linearGradient> |  | ||||||
|     <radialGradient |  | ||||||
|        inkscape:collect="always" |  | ||||||
|        xlink:href="#linearGradient3558" |  | ||||||
|        id="radialGradient3564" |  | ||||||
|        cx="21.761711" |  | ||||||
|        cy="23.07144" |  | ||||||
|        fx="21.761711" |  | ||||||
|        fy="23.07144" |  | ||||||
|        r="15.571428" |  | ||||||
|        gradientTransform="matrix(0.977282,3.554943e-8,-8.305337e-10,0.651376,-0.794430,15.82896)" |  | ||||||
|        gradientUnits="userSpaceOnUse" /> |  | ||||||
|     <linearGradient |  | ||||||
|        inkscape:collect="always" |  | ||||||
|        xlink:href="#linearGradient5783" |  | ||||||
|        id="linearGradient5789" |  | ||||||
|        x1="23.505953" |  | ||||||
|        y1="5.7753429" |  | ||||||
|        x2="20.604948" |  | ||||||
|        y2="29.85923" |  | ||||||
|        gradientUnits="userSpaceOnUse" /> |  | ||||||
|   </defs> |  | ||||||
|   <sodipodi:namedview |  | ||||||
|      id="base" |  | ||||||
|      pagecolor="#ffffff" |      pagecolor="#ffffff" | ||||||
|      bordercolor="#666666" |      bordercolor="#666666" | ||||||
|      borderopacity="0.23529412" |      borderopacity="1" | ||||||
|      inkscape:pageopacity="0.0" |      objecttolerance="10" | ||||||
|  |      gridtolerance="10" | ||||||
|  |      guidetolerance="10" | ||||||
|  |      inkscape:pageopacity="0" | ||||||
|      inkscape:pageshadow="2" |      inkscape:pageshadow="2" | ||||||
|      inkscape:zoom="1" |      inkscape:window-width="1920" | ||||||
|      inkscape:cx="35.082015" |      inkscape:window-height="1033" | ||||||
|      inkscape:cy="26.818745" |      id="namedview4585" | ||||||
|      inkscape:current-layer="layer1" |  | ||||||
|      showgrid="false" |      showgrid="false" | ||||||
|      inkscape:grid-bbox="true" |      inkscape:zoom="14.3" | ||||||
|      inkscape:document-units="px" |      inkscape:cx="30" | ||||||
|      inkscape:window-width="770" |      inkscape:cy="30" | ||||||
|      inkscape:window-height="716" |      inkscape:window-x="-2" | ||||||
|      inkscape:window-x="217" |      inkscape:window-y="24" | ||||||
|      inkscape:window-y="575" |      inkscape:window-maximized="1" | ||||||
|      stroke="#d3d7cf" |      inkscape:current-layer="svg4573" /><g | ||||||
|      inkscape:showpageshadow="false" /> |      id="Layer_x0020_3" | ||||||
|   <metadata |      style="fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;"><g | ||||||
|      id="metadata79611"> |        id="g4576"><path | ||||||
|     <rdf:RDF> |          style="fill:none;stroke:#FFFFFF;stroke-width:7.504;stroke-linejoin:round;" | ||||||
|       <cc:Work |          d="M18.3,5.4c-0.7,0-1.3,0.6-1.3,1.3v18.9c0,0.4,0.2,0.8,0.5,1l6.1,4.6c0.5,0.4,1.1,0.3,1.6-0.1l5.1-4.4c0.3-0.2,0.4-0.6,0.4-0.9V15c0-0.7-0.6-1.3-1.3-1.3c-0.7,0-1.3,0.6-1.3,1.3c0,0,0,9.1,0,10.1c-0.6,0.5-2.9,2.5-3.9,3.4     c-1.1-0.8-4.1-3.1-4.8-3.6c0-1.1,0-15,0-17.1c1.9,0,10.3,0,12.2,0c0,2.2,0,24.5,0,25.6c-0.8,0.6-6.4,5.1-7.6,6.1c-1.2-0.9-7.1-5.1-7.9-5.7c0-1.2,0-18.5,0-18.5c0-0.7-0.6-1.3-1.3-1.3c-0.7,0-1.3,0.6-1.3,1.3v19.2c0,0.4,0.2,0.8,0.5,1l9.2,6.7     c0.5,0.3,1.1,0.3,1.5,0l8.8-7.1c0.3-0.2,0.5-0.6,0.5-1V6.6c0-0.7-0.6-1.3-1.3-1.3H18.3z" | ||||||
|          rdf:about=""> |          id="path4578" /><path | ||||||
|         <dc:format>image/svg+xml</dc:format> |          style="fill:none;stroke-width:3.3351;stroke-linecap:round;stroke-linejoin:round;" | ||||||
|         <dc:type |          d="M14.3,15.3v19.2l9.9,6.7l8.8-7.1V6.6H18.3v18.9l6.1,4.6l5.1-4.5V15" | ||||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |          id="path4580" /></g></g><g | ||||||
|         <dc:title>Mail Attachment</dc:title> |      id="crop_x0020_marks" | ||||||
|         <dc:date>2005-11-04</dc:date> |      style="fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;"><path | ||||||
|         <dc:creator> |        style="fill:none;stroke:none;" | ||||||
|           <cc:Agent> |        d="M48,48H0V0h48v48z" | ||||||
|             <dc:title>Andreas Nilsson</dc:title> |        id="path4583" /></g></svg> | ||||||
|           </cc:Agent> |  | ||||||
|         </dc:creator> |  | ||||||
|         <dc:source>http://tango-project.org</dc:source> |  | ||||||
|         <dc:subject> |  | ||||||
|           <rdf:Bag> |  | ||||||
|             <rdf:li>attachment</rdf:li> |  | ||||||
|             <rdf:li>file</rdf:li> |  | ||||||
|           </rdf:Bag> |  | ||||||
|         </dc:subject> |  | ||||||
|         <cc:license |  | ||||||
|            rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" /> |  | ||||||
|         <dc:contributor> |  | ||||||
|           <cc:Agent> |  | ||||||
|             <dc:title>Garrett Lesage</dc:title> |  | ||||||
|           </cc:Agent> |  | ||||||
|         </dc:contributor> |  | ||||||
|       </cc:Work> |  | ||||||
|       <cc:License |  | ||||||
|          rdf:about="http://creativecommons.org/licenses/by-sa/2.0/"> |  | ||||||
|         <cc:permits |  | ||||||
|            rdf:resource="http://web.resource.org/cc/Reproduction" /> |  | ||||||
|         <cc:permits |  | ||||||
|            rdf:resource="http://web.resource.org/cc/Distribution" /> |  | ||||||
|         <cc:requires |  | ||||||
|            rdf:resource="http://web.resource.org/cc/Notice" /> |  | ||||||
|         <cc:requires |  | ||||||
|            rdf:resource="http://web.resource.org/cc/Attribution" /> |  | ||||||
|         <cc:permits |  | ||||||
|            rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> |  | ||||||
|         <cc:requires |  | ||||||
|            rdf:resource="http://web.resource.org/cc/ShareAlike" /> |  | ||||||
|       </cc:License> |  | ||||||
|     </rdf:RDF> |  | ||||||
|   </metadata> |  | ||||||
|   <g |  | ||||||
|      id="layer1" |  | ||||||
|      inkscape:label="Layer 1" |  | ||||||
|      inkscape:groupmode="layer"> |  | ||||||
|     <path |  | ||||||
|        style="fill:none;stroke:#888a85;stroke-width:3.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" |  | ||||||
|        id="path7057" |  | ||||||
|        d="M 21.326337,9.3278633 L 10.449186,27.94227 C 8.5266861,31.23365 9.6775753,35.481172 13.008091,37.38221 L 15.102397,38.579075 C 18.434077,40.480111 22.732254,39.341738 24.655919,36.05036 L 36.41168,15.928621 C 38.335346,12.636117 37.625044,8.6405654 34.835356,7.0477444 C 32.045435,5.4549233 28.187846,6.8452672 26.265346,10.137772 L 18.109581,24.099704 C 16.186149,27.391081 15.978909,30.871442 17.647547,31.836583 C 19.317351,32.799475 22.257398,30.893938 24.179898,27.602558 L 28.142388,20.81957" /> |  | ||||||
|     <path |  | ||||||
|        style="fill:none;stroke:url(#linearGradient5789);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" |  | ||||||
|        id="path7053" |  | ||||||
|        d="M 21.326337,9.2155349 L 10.449186,27.829941 C 8.5266861,31.121321 9.6775753,35.368843 13.008091,37.269881 L 15.102397,38.466746 C 18.434077,40.367782 22.732254,39.229409 24.655919,35.938031 L 36.41168,15.816292 C 38.335346,12.523788 37.625044,8.528237 34.835356,6.935416 C 32.045435,5.3425949 28.187846,6.7329388 26.265346,10.025444 L 18.109581,23.987375 C 16.186149,27.278752 15.978909,30.759113 17.647547,31.724254 C 19.317351,32.687146 22.257398,30.781609 24.179898,27.490229 L 28.142388,20.707241" /> |  | ||||||
|     <path |  | ||||||
|        sodipodi:type="arc" |  | ||||||
|        style="opacity:0.3125;color:#000000;fill:url(#radialGradient3564);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" |  | ||||||
|        id="path3556" |  | ||||||
|        sodipodi:cx="22.571428" |  | ||||||
|        sodipodi:cy="30.857143" |  | ||||||
|        sodipodi:rx="15.571428" |  | ||||||
|        sodipodi:ry="10.142858" |  | ||||||
|        d="M 38.142857 30.857143 A 15.571428 10.142858 0 1 1  7,30.857143 A 15.571428 10.142858 0 1 1  38.142857 30.857143 z" |  | ||||||
|        transform="matrix(1.316514,0.000000,0.000000,0.246479,-2.215601,32.89436)" /> |  | ||||||
|   </g> |  | ||||||
| </svg> |  | ||||||
| Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 2.6 KiB | 
| @@ -1,12 +1,40 @@ | |||||||
| <form id="chat" autocomplete="off" onsubmit="sendmessage(this.elements['recv'].value, this.elements['msg'].value)"> | <div id="message"> | ||||||
|  |   <form id="chat" autocomplete="off" onsubmit="sendmessage(this.elements['recv'].value, this.elements['msg'].value)"> | ||||||
|     <input placeholder="receiver" autocomplete="off" type="text" id="recv" oninput="checkpartner(this.value)" /> |     <input placeholder="receiver" autocomplete="off" type="text" id="recv" oninput="checkpartner(this.value)" /> | ||||||
|     <input placeholder="message" autocomplete="off" type="text" id="msg"/> |     <input placeholder="message" autocomplete="off" type="text" id="msg"/> | ||||||
|   <label class="icon" for="file" style="flex-grow: 0"><img style="width: 2em; height: 2em" src="attachment.svg"/></label> |     <div class="buttongroup"> | ||||||
|   <input class="icon" autocomplete="off" type="file" id="file" style="display:none"/> |       <span class="toolbutton"> | ||||||
|  |         <label for="photo"><img src="photo.svg"/></label> | ||||||
|  |         <input autocomplete="off" type="file" accept="image/*" id="photo" multiple /> | ||||||
|  |       </span> | ||||||
|  |       <!-- | ||||||
|  |       <span class="toolbutton"> | ||||||
|  |         <label for="file"><img src="video.svg"/></label> | ||||||
|  |         <input autocomplete="off" type="file" accept="video/*" id="video"/> | ||||||
|  |       </span> | ||||||
|  |       <span class="toolbutton"> | ||||||
|  |         <label for="file"><img src="audio.svg"/></label> | ||||||
|  |         <input autocomplete="off" type="file" accept="audio/*" id="audio"/> | ||||||
|  |       </span> | ||||||
|  |       <span class="toolbutton"> | ||||||
|  |         <label for="file"><img src="attachment.svg"/></label> | ||||||
|  |         <input autocomplete="off" type="file" id="file"/> | ||||||
|  |       </span> | ||||||
|  |       --> | ||||||
|  |       <span class="toolbutton"> | ||||||
|  |         <label for="send"><img src="send.svg"/></label> | ||||||
|         <input type="submit" id="send" disabled/> |         <input type="submit" id="send" disabled/> | ||||||
| </form> |       </span> | ||||||
|  |       <span class="toolbutton"> | ||||||
|  |         <label for="reset"><img src="abort.svg" /></label> | ||||||
|  |         <input type="reset" id="reset" onclick="clearmessage();" /> | ||||||
|  |       </span> | ||||||
|  |     </div> | ||||||
|  |   </form> | ||||||
|  |   <div id="preview"></div> | ||||||
|  | </div> | ||||||
| <div id="msgs"></div> | <div id="msgs"></div> | ||||||
| <script> | <script> | ||||||
|   $("#file").change(function(evt){fileupload(evt)}); |   $("#file,#photo,#audio,#video").change(function(evt){fileupload(evt)}); | ||||||
|   if (!window.FileReader) $("#file").hide(); // not supported by browser |   if (!window.FileReader) $("#file,#photo,#audio,#video").hide(); // not supported by browser | ||||||
| </script> | </script> | ||||||
|   | |||||||
| @@ -4,7 +4,9 @@ try { | |||||||
|   $db = new mysqli("mysql", "root", $_SERVER["MYSQL_ENV_MYSQL_ROOT_PASSWORD"]); |   $db = new mysqli("mysql", "root", $_SERVER["MYSQL_ENV_MYSQL_ROOT_PASSWORD"]); | ||||||
|   $db->query("create database if not exists safechat;"); |   $db->query("create database if not exists safechat;"); | ||||||
|   $db->select_db("safechat"); |   $db->select_db("safechat"); | ||||||
|   $db->query('create table if not exists message (id int primary key not null auto_increment, time timestamp default current_timestamp, user varchar(50) not null, msg text not null);'); |   $db->query('create table if not exists message (id int primary key not null auto_increment, time timestamp default current_timestamp, user varchar(50) not null, msg longtext not null);'); | ||||||
|  |   $db->query('set global max_allowed_packet=1000000000'); | ||||||
|  |   $db->query('set global net_buffer_length=1000000'); | ||||||
| } catch (Exception $e) { | } catch (Exception $e) { | ||||||
|   echo json_encode(null); |   echo json_encode(null); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -3,6 +3,12 @@ | |||||||
|   padding: 0; |   padding: 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @media (min-resolution: 120dpi) { | ||||||
|  |   html { | ||||||
|  |     font-size: 120%; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| p { | p { | ||||||
|   padding: .5em 0 1em 0; |   padding: .5em 0 1em 0; | ||||||
| } | } | ||||||
| @@ -31,6 +37,23 @@ form input#msg { | |||||||
|   flex-grow: 4; |   flex-grow: 4; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .buttongroup { | ||||||
|  |   flex-grow: 0; | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: row; | ||||||
|  |   flex-wrap: nowrap; | ||||||
|  | } | ||||||
|  | .buttongroup .toolbutton { | ||||||
|  |   flex-grow: 1; | ||||||
|  |   text-align: center; | ||||||
|  | } | ||||||
|  | .toolbutton label img { | ||||||
|  |   height: 1.5em; | ||||||
|  | } | ||||||
|  | .toolbutton input { | ||||||
|  |   display:none; | ||||||
|  | } | ||||||
|  |  | ||||||
| table { | table { | ||||||
|   width: 100%; |   width: 100%; | ||||||
| } | } | ||||||
| @@ -74,13 +97,16 @@ td:last-child { | |||||||
|   } |   } | ||||||
| } | } | ||||||
| #status.error { | #status.error { | ||||||
|   background-color: lightred; |   background-color: red; | ||||||
|  |   color: black; | ||||||
| } | } | ||||||
| #status.notice { | #status.notice { | ||||||
|   background-color: yellow; |   background-color: yellow; | ||||||
|  |   color: black; | ||||||
| } | } | ||||||
| #status.success { | #status.success { | ||||||
|   background-color: lightgreen; |   background-color: lightgreen; | ||||||
|  |   color: black; | ||||||
| } | } | ||||||
|  |  | ||||||
| #main { | #main { | ||||||
| @@ -93,36 +119,58 @@ td:last-child { | |||||||
| #msgs .msg { | #msgs .msg { | ||||||
|   border: 1px solid black; |   border: 1px solid black; | ||||||
|   margin: 1ex; |   margin: 1ex; | ||||||
|   padding: 1ex; |  | ||||||
|   border-radius: 2ex; |   border-radius: 2ex; | ||||||
|   -moz-border-radius: 1em; |   -moz-border-radius: 2ex; | ||||||
|   -webkit-border-radius: 1em; |   -webkit-border-radius: 2ex; | ||||||
|  |   display: block; | ||||||
|  |   width: auto; | ||||||
|  |   height: auto; | ||||||
|  |   max-width: 60%; | ||||||
| } | } | ||||||
| #msgs .me { | #msgs .me { | ||||||
|   float: left; |   float: left; | ||||||
|  |   background-color: lightgray; | ||||||
| } | } | ||||||
| #msgs .other { | #msgs .other { | ||||||
|   float: right; |   float: right; | ||||||
|  |   background-color: lightyellow; | ||||||
| } | } | ||||||
| #msgs .msg .header { | #msgs .msg .header { | ||||||
|   border-bottom: 1px solid black; |   border: 1px solid black; | ||||||
|  |   border-radius: 2ex 2ex 0 0; | ||||||
|  |   -moz-border-radius: 2ex 2ex 0 0; | ||||||
|  |   -webkit-border-radius: 2ex 2ex 0 0; | ||||||
|  |   /*border-radius: 2ex; | ||||||
|  |   -moz-border-radius: 2ex; | ||||||
|  |   -webkit-border-radius: 2ex;*/ | ||||||
|   margin-bottom: .25ex; |   margin-bottom: .25ex; | ||||||
|   padding-bottom: .25ex; |   padding-bottom: .25ex; | ||||||
|   position: relative; |   position: relative; | ||||||
|   height: 1em; |   height: 1em; | ||||||
|  |   padding: .5ex 1ex .5ex 1ex; | ||||||
|  | } | ||||||
|  | #msgs .msg .header { | ||||||
|  |   background-color: lightgreen; | ||||||
| } | } | ||||||
| #msgs .msg .header .date { | #msgs .msg .header .date { | ||||||
|   font-size: xx-small; |   font-size: xx-small; | ||||||
|   float: left; |   float: left; | ||||||
|   /*position: absolute; |   padding: 0 1ex 0 0; | ||||||
|   left: 0;*/ |  | ||||||
| } | } | ||||||
| #msgs .msg .header .sender { | #msgs .msg .header .sender { | ||||||
|   font-size: small; |   font-size: small; | ||||||
|   float: right; |   float: right; | ||||||
|   /*position: absolute; |   padding: 0 0 0 1ex; | ||||||
|   right: 0;*/ |  | ||||||
| } | } | ||||||
| #msgs .msg .text { | #msgs .msg .text { | ||||||
|   float: left; |   float: left; | ||||||
|  |   padding: .5ex 1ex .5ex 1ex; | ||||||
|  | } | ||||||
|  | #msgs .msg img { | ||||||
|  |   display: block; | ||||||
|  |   width: 99%; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #preview img { | ||||||
|  |   height: 4em; | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										105
									
								
								html/safechat.js
									
									
									
									
									
								
							
							
						
						
									
										105
									
								
								html/safechat.js
									
									
									
									
									
								
							| @@ -1,5 +1,6 @@ | |||||||
| var password = null; | var password = null; // password, only stored temporary, until reload | ||||||
| var username = null; | var username = null; // username, only used during registration | ||||||
|  | var filecontent = new Array(); // temporary storage for attachments | ||||||
|  |  | ||||||
| function error(data, stay) { | function error(data, stay) { | ||||||
|     $("#status").fadeOut("slow", function() { |     $("#status").fadeOut("slow", function() { | ||||||
| @@ -11,7 +12,7 @@ function error(data, stay) { | |||||||
|                 $("#status").html(data); |                 $("#status").html(data); | ||||||
|                 console.log("error: "+data); |                 console.log("error: "+data); | ||||||
|             } else { |             } else { | ||||||
|                 $("#status").html('<pre>'+JSON.stringify(data)+'</pre>'); |                 $("#status").html('error'); | ||||||
|                 console.log("error: "+JSON.stringify(data)); |                 console.log("error: "+JSON.stringify(data)); | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
| @@ -151,18 +152,46 @@ function userid() { | |||||||
|     return publicKey().keys[0].getUserIds()[0]; |     return publicKey().keys[0].getUserIds()[0]; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | function clearmessage() { | ||||||
|  |     filecontent = new Array(); | ||||||
|  |     $('#preview').empty(); | ||||||
|  |     $("#msg").val(""); | ||||||
|  |     notice("message cleared"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function attachments(files, id) { | ||||||
|  |     if (files) files.forEach(function(file) { | ||||||
|  |         //if (file.content.length<1000000) { | ||||||
|  |             var img = document.createElement('img'); | ||||||
|  |             img.src = 'data:'+file.type+';base64,' + file.content; | ||||||
|  |             $(id).append(img); | ||||||
|  |         //} | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  |  | ||||||
| function fileupload(evt) { | function fileupload(evt) { | ||||||
|     if (!window.FileReader) |     if (!window.FileReader) | ||||||
|         return error("your browser dows not support file upload", true); |         return error("your browser dows not support file upload", true); | ||||||
|  |     for (var i=0, f; f=evt.target.files[i]; ++i) { | ||||||
|  |         var file = f; | ||||||
|         var reader = new FileReader(); |         var reader = new FileReader(); | ||||||
|         reader.onload = function(evt) { |         reader.onload = function(evt) { | ||||||
|         if (evt.target.readyState!=2) |  | ||||||
|             return notice("ReadyState="+evt.target.readyState); |  | ||||||
|             if (evt.target.error) return error("error reading file", true); |             if (evt.target.error) return error("error reading file", true); | ||||||
|         filecontent = evt.target.result; |             if (evt.target.readyState==0) return notice("waiting for data ..."); | ||||||
|         success(filecontent); |             if (evt.target.readyState==1) return notice("loading data ..."); | ||||||
|  |             var base64 = btoa(evt.target.result); | ||||||
|  |             filecontent.push({type: file.type, content: base64}); | ||||||
|  |             if (file.type.match('^image/')) { | ||||||
|  |                 var img = document.createElement('img'); | ||||||
|  |                 img.src = 'data:'+file.type+';base64,' + base64; | ||||||
|  |                 $("#preview").append(img); | ||||||
|  |                 success('image of type '+file.type+' is ready to be sent'); | ||||||
|  |             } else { | ||||||
|  |                 success('file of type '+file.type+' is ready to be sent'); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         reader.readAsBinaryString(file); | ||||||
|     } |     } | ||||||
|     reader.readAsText(evt.target.files[0]); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| function setreceiver(name) { | function setreceiver(name) { | ||||||
| @@ -171,83 +200,101 @@ function setreceiver(name) { | |||||||
|     $("#msg").focus(); |     $("#msg").focus(); | ||||||
| } | } | ||||||
|  |  | ||||||
| var startmsg = 0; | var startmsg = 0; // number of last downloaded message | ||||||
| function get() { | function get() { | ||||||
|     var beeped = false; |     var beeped = false; | ||||||
|     $.post("get.php", {start: startmsg}).done(function(res) { |     $.post("get.php", {start: startmsg}).done(function(res) { | ||||||
|         var msgs = JSON.parse(res); |         var msgs = JSON.parse(res); | ||||||
|         if (msgs) { |         if (msgs) { | ||||||
|             msgs.forEach(function(e) { |             msgs.forEach(function(e) { | ||||||
|                 if (startmsg<Number(e["id"])) startmsg = Number(e["id"]); |                 if (startmsg<Number(e.id)) startmsg = Number(e.id); | ||||||
|                 $.post("pubkey.php", {user: e["user"]}).done(function(pk) { |                 $.post("pubkey.php", {user: e.user}).done(function(pk) { | ||||||
|                     var res=JSON.parse(pk); |                     var res=JSON.parse(pk); | ||||||
|                     var key=openpgp.key.readArmored(res); |                     var key=openpgp.key.readArmored(res); | ||||||
|                     if (!res||key.err) { |                     if (!res||key.err) { | ||||||
|                         error("key of receiver not found", true); |                         setTimeout(get, 10000); | ||||||
|                     } else { |                         return error("key of receiver not found", true); | ||||||
|                         var message = openpgp.message.readArmored(e["msg"]); |                     } | ||||||
|  |                     var message = openpgp.message.readArmored(e.msg); | ||||||
|                     var privkey = privateKey().keys[0]; |                     var privkey = privateKey().keys[0]; | ||||||
|                     if (privkey.decrypt(password)) |                     if (privkey.decrypt(password)) | ||||||
|                         openpgp.decryptAndVerifyMessage(privkey, key.keys, message) |                         openpgp.decryptAndVerifyMessage(privkey, key.keys, message) | ||||||
|                         .then(function(msg) { |                         .then(function(msg) { | ||||||
|  |                             var message = JSON.parse(msg.text); | ||||||
|                             $("#msgs") // todo: check msg.signatures[0].valid |                             $("#msgs") // todo: check msg.signatures[0].valid | ||||||
|                                     .prepend('<div id="id'+(e["id"])+'" class="msg '+ |                                 .prepend('<div id="id'+(e.id)+'" class="msg '+ | ||||||
|                                              (e["user"]==userid()?"me":"other")+ |                                          (e.user==userid()?"me":"other")+ | ||||||
|                                          '"><div class="header">'+ |                                          '"><div class="header">'+ | ||||||
|                                          '<span class="date">'+ |                                          '<span class="date">'+ | ||||||
|                                              (new Date(1000*Number(e["time"]))).toLocaleString()+ |                                          (new Date(1000*Number(e.time))).toLocaleString()+ | ||||||
|                                          '</span><span class="sender">'+ |                                          '</span><span class="sender">'+ | ||||||
|                                          '<a href="javascript:void(0)" onclick="setreceiver(this.innerHTML)">'+ |                                          '<a href="javascript:void(0)" onclick="setreceiver(this.innerHTML)">'+ | ||||||
|                                              e["user"]+ |                                          e.user+ | ||||||
|                                              '</a></span></div><div class="text">'+ |                                          '</a></span></div>'+ | ||||||
|                                              msg.text+ |                                          '<div class="text">'+ | ||||||
|  |                                          message.text+ | ||||||
|                                          '</div></div><div class="clear"/>'); |                                          '</div></div><div class="clear"/>'); | ||||||
|                                 $('#id'+(e["id"])).emoticonize(); |                             attachments(message.files, '#id'+e.id+' .text'); | ||||||
|  |                             $('#id'+e.id).emoticonize(); | ||||||
|                             if (!beeped) |                             if (!beeped) | ||||||
|                                 (new Audio("A-Tone-His_Self-1266414414.mp3")) |                                 (new Audio("A-Tone-His_Self-1266414414.mp3")) | ||||||
|                                 .play(); |                                 .play(); | ||||||
|                             beeped = true; |                             beeped = true; | ||||||
|  |                         }) | ||||||
|  |                         .catch(function(e) { | ||||||
|  |                             // not for me | ||||||
|                         }); |                         }); | ||||||
| //                            .catch(function(e) { |  | ||||||
| //                                error("decryption of message failed", true); |  | ||||||
| //                            }); |  | ||||||
|                     } |  | ||||||
|                 }).fail(function(e) { |                 }).fail(function(e) { | ||||||
|                     error("get sender's key from server failed", true); |                     error("get sender's key from server failed", true); | ||||||
|                 }); |                 }); | ||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
|  |     }).fail(function(e) { | ||||||
|  |         error("get messages failed") | ||||||
|  |     }); | ||||||
|     setTimeout(get, 10000); |     setTimeout(get, 10000); | ||||||
|     }).fail(error); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| function sendmessage(recv, txt) { | function sendmessage(recv, txt) { | ||||||
|  |     notice("1/3 preparing message ..."); | ||||||
|  |     $("#message").fadeOut("slow"); | ||||||
|     $.post("pubkey.php", {user: recv}).done(function(pk) { |     $.post("pubkey.php", {user: recv}).done(function(pk) { | ||||||
|         var res=JSON.parse(pk); |         var res=JSON.parse(pk); | ||||||
|         var key=openpgp.key.readArmored(res); |         var key=openpgp.key.readArmored(res); | ||||||
|         if (!res||key.err) { |         if (!res||key.err) { | ||||||
|  |             $("#message").fadeIn("slow"); | ||||||
|             error("key of receiver not found", true); |             error("key of receiver not found", true); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         var privkey = privateKey().keys[0]; |         var privkey = privateKey().keys[0]; | ||||||
|         privkey.decrypt(password); |         privkey.decrypt(password); | ||||||
|         openpgp.signAndEncryptMessage(key.keys.concat(publicKey().keys), privkey, txt) |         var message = JSON.stringify({text: txt, files: filecontent}); | ||||||
|  |         notice("2/3 encrypting message ..."); | ||||||
|  |         openpgp.signAndEncryptMessage(key.keys.concat(publicKey().keys), privkey, message) | ||||||
|         .then(function(msg) { |         .then(function(msg) { | ||||||
|  |             notice("3/3 sending message ..."); | ||||||
|             $.post("send.php", {user: userid(), msg: msg}) |             $.post("send.php", {user: userid(), msg: msg}) | ||||||
|                 .done(function(res) { |                 .done(function(res) { | ||||||
|                     if (JSON.parse(res)) { |                     if (JSON.parse(res)) { | ||||||
|                         $("#msg").val(""); |                         $("#message").fadeIn("slow"); | ||||||
|  |                         clearmessage(); | ||||||
|                         success("message sent"); |                         success("message sent"); | ||||||
|                     } else error("error sending message", true); |                     } else { | ||||||
|  |                         $("#message").fadeIn("slow"); | ||||||
|  |                         error("error sending message", true); | ||||||
|  |                     } | ||||||
|                 }) |                 }) | ||||||
|                 .fail(error); |                 .fail(error); | ||||||
|         }) |         }) | ||||||
|         .catch(function(e) { |         .catch(function(e) { | ||||||
|  |             $("#message").fadeIn("slow"); | ||||||
|             error("encryption of message failed", true); |             error("encryption of message failed", true); | ||||||
|         }); |         }); | ||||||
|     }).fail(function(e) { |     }).fail(function(e) { | ||||||
|  |         $("#message").fadeIn("slow"); | ||||||
|         error("get receiver's key from server failed", true); |         error("get receiver's key from server failed", true); | ||||||
|     }); |     }); | ||||||
|  |     $("#message").fadeIn("slow"); | ||||||
| } | } | ||||||
|  |  | ||||||
| function setpw(pwd) { | function setpw(pwd) { | ||||||
|   | |||||||
| @@ -4,7 +4,12 @@ try { | |||||||
|   $user = $db->real_escape_string($_REQUEST['user']); |   $user = $db->real_escape_string($_REQUEST['user']); | ||||||
|   $msg = $db->real_escape_string($_REQUEST['msg']); |   $msg = $db->real_escape_string($_REQUEST['msg']); | ||||||
|   $q = $db->query("insert into message (user, msg) values ('$user', '$msg');"); |   $q = $db->query("insert into message (user, msg) values ('$user', '$msg');"); | ||||||
|  |   if ($q) { | ||||||
|     echo json_encode(true); |     echo json_encode(true); | ||||||
|  |   } else { | ||||||
|  |     error_log("Error storing message: ".$db->error); | ||||||
|  |     echo json_encode(false); | ||||||
|  |   } | ||||||
| } catch (Exception $e) { | } catch (Exception $e) { | ||||||
|   echo json_encode(false); |   echo json_encode(false); | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user