A little more work on the threaded view
authorArt Cancro <ajc@citadel.org>
Sun, 28 Jan 2018 06:09:07 +0000 (01:09 -0500)
committerArt Cancro <ajc@citadel.org>
Sun, 28 Jan 2018 06:09:07 +0000 (01:09 -0500)
webcit-ng/static/index.html
webcit-ng/static/js/main.js
webcit-ng/static/w3.css [new file with mode: 0644]
webcit-ng/threaded_view.c

index 2fa6013..5245092 100644 (file)
@@ -1,9 +1,9 @@
 <!DOCTYPE html>
 <html>
-<title>W3.CSS Template</title>
+<title>Citadel</title>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1">
-<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
+<link rel="stylesheet" href="w3.css">
 <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway">
 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
 <style>
@@ -22,7 +22,7 @@ html,body,h1,h2,h3,h4,h5 {font-family: "Raleway", sans-serif}
 <nav class="w3-sidebar w3-collapse w3-white w3-animate-left" style="z-index:3;width:300px;" id="sidebar"><br>
   <div class="w3-container w3-row">
     <div class="w3-col s4">
-      <img src="/w3images/avatar2.png" class="w3-circle w3-margin-right" style="width:46px">
+       <i class="fa fa-user-circle fa-3x"></i>
     </div>
     <div class="w3-col s8 w3-bar">
       <span id="current_user">Welcome, <strong>Mike</strong></span><br>
index 6c4a1a5..c711e96 100644 (file)
@@ -163,6 +163,7 @@ function update_banner() {
        detect_logged_in();
        if (current_room) {
                document.getElementById("ctdl_banner_title").innerHTML = current_room;
+               document.title = current_room;
        }
        else {
                document.getElementById("ctdl_banner_title").innerHTML = serv_info.serv_humannode;
diff --git a/webcit-ng/static/w3.css b/webcit-ng/static/w3.css
new file mode 100644 (file)
index 0000000..1400390
--- /dev/null
@@ -0,0 +1,231 @@
+/* W3.CSS 4.09 January 2018 by Jan Egil and Borge Refsnes */\r
+html{box-sizing:border-box}*,*:before,*:after{box-sizing:inherit}\r
+/* Extract from normalize.css by Nicolas Gallagher and Jonathan Neal git.io/normalize */\r
+html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}\r
+article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}\r
+audio,canvas,progress,video{display:inline-block}progress{vertical-align:baseline}\r
+audio:not([controls]){display:none;height:0}[hidden],template{display:none}\r
+a{background-color:transparent;-webkit-text-decoration-skip:objects}\r
+a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}\r
+dfn{font-style:italic}mark{background:#ff0;color:#000}\r
+small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}\r
+sub{bottom:-0.25em}sup{top:-0.5em}figure{margin:1em 40px}img{border-style:none}svg:not(:root){overflow:hidden}\r
+code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}hr{box-sizing:content-box;height:0;overflow:visible}\r
+button,input,select,textarea{font:inherit;margin:0}optgroup{font-weight:bold}\r
+button,input{overflow:visible}button,select{text-transform:none}\r
+button,html [type=button],[type=reset],[type=submit]{-webkit-appearance:button}\r
+button::-moz-focus-inner, [type=button]::-moz-focus-inner, [type=reset]::-moz-focus-inner, [type=submit]::-moz-focus-inner{border-style:none;padding:0}\r
+button:-moz-focusring, [type=button]:-moz-focusring, [type=reset]:-moz-focusring, [type=submit]:-moz-focusring{outline:1px dotted ButtonText}\r
+fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:.35em .625em .75em}\r
+legend{color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}\r
+[type=checkbox],[type=radio]{padding:0}\r
+[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}\r
+[type=search]{-webkit-appearance:textfield;outline-offset:-2px}\r
+[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}\r
+::-webkit-input-placeholder{color:inherit;opacity:0.54}\r
+::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}\r
+/* End extract */\r
+html,body{font-family:Verdana,sans-serif;font-size:15px;line-height:1.5}html{overflow-x:hidden}\r
+h1{font-size:36px}h2{font-size:30px}h3{font-size:24px}h4{font-size:20px}h5{font-size:18px}h6{font-size:16px}.w3-serif{font-family:serif}\r
+h1,h2,h3,h4,h5,h6{font-family:"Segoe UI",Arial,sans-serif;font-weight:400;margin:10px 0}.w3-wide{letter-spacing:4px}\r
+hr{border:0;border-top:1px solid #eee;margin:20px 0}\r
+.w3-image{max-width:100%;height:auto}img{vertical-align:middle}a{color:inherit}\r
+.w3-table,.w3-table-all{border-collapse:collapse;border-spacing:0;width:100%;display:table}.w3-table-all{border:1px solid #ccc}\r
+.w3-bordered tr,.w3-table-all tr{border-bottom:1px solid #ddd}.w3-striped tbody tr:nth-child(even){background-color:#f1f1f1}\r
+.w3-table-all tr:nth-child(odd){background-color:#fff}.w3-table-all tr:nth-child(even){background-color:#f1f1f1}\r
+.w3-hoverable tbody tr:hover,.w3-ul.w3-hoverable li:hover{background-color:#ccc}.w3-centered tr th,.w3-centered tr td{text-align:center}\r
+.w3-table td,.w3-table th,.w3-table-all td,.w3-table-all th{padding:8px 8px;display:table-cell;text-align:left;vertical-align:top}\r
+.w3-table th:first-child,.w3-table td:first-child,.w3-table-all th:first-child,.w3-table-all td:first-child{padding-left:16px}\r
+.w3-btn,.w3-button{border:none;display:inline-block;padding:8px 16px;vertical-align:middle;overflow:hidden;text-decoration:none;color:inherit;background-color:inherit;text-align:center;cursor:pointer;white-space:nowrap}\r
+.w3-btn:hover{box-shadow:0 8px 16px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19)}\r
+.w3-btn,.w3-button{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}   \r
+.w3-disabled,.w3-btn:disabled,.w3-button:disabled{cursor:not-allowed;opacity:0.3}.w3-disabled *,:disabled *{pointer-events:none}\r
+.w3-btn.w3-disabled:hover,.w3-btn:disabled:hover{box-shadow:none}\r
+.w3-badge,.w3-tag{background-color:#000;color:#fff;display:inline-block;padding-left:8px;padding-right:8px;text-align:center}.w3-badge{border-radius:50%}\r
+.w3-ul{list-style-type:none;padding:0;margin:0}.w3-ul li{padding:8px 16px;border-bottom:1px solid #ddd}.w3-ul li:last-child{border-bottom:none}\r
+.w3-tooltip,.w3-display-container{position:relative}.w3-tooltip .w3-text{display:none}.w3-tooltip:hover .w3-text{display:inline-block}\r
+.w3-ripple:active{opacity:0.5}.w3-ripple{transition:opacity 0s}\r
+.w3-input{padding:8px;display:block;border:none;border-bottom:1px solid #ccc;width:100%}\r
+.w3-select{padding:9px 0;width:100%;border:none;border-bottom:1px solid #ccc}\r
+.w3-dropdown-click,.w3-dropdown-hover{position:relative;display:inline-block;cursor:pointer}\r
+.w3-dropdown-hover:hover .w3-dropdown-content{display:block}\r
+.w3-dropdown-hover:first-child,.w3-dropdown-click:hover{background-color:#ccc;color:#000}\r
+.w3-dropdown-hover:hover > .w3-button:first-child,.w3-dropdown-click:hover > .w3-button:first-child{background-color:#ccc;color:#000}\r
+.w3-dropdown-content{cursor:auto;color:#000;background-color:#fff;display:none;position:absolute;min-width:160px;margin:0;padding:0;z-index:1}\r
+.w3-check,.w3-radio{width:24px;height:24px;position:relative;top:6px}\r
+.w3-sidebar{height:100%;width:200px;background-color:#fff;position:fixed!important;z-index:1;overflow:auto}\r
+.w3-bar-block .w3-dropdown-hover,.w3-bar-block .w3-dropdown-click{width:100%}\r
+.w3-bar-block .w3-dropdown-hover .w3-dropdown-content,.w3-bar-block .w3-dropdown-click .w3-dropdown-content{min-width:100%}\r
+.w3-bar-block .w3-dropdown-hover .w3-button,.w3-bar-block .w3-dropdown-click .w3-button{width:100%;text-align:left;padding:8px 16px}\r
+.w3-main,#main{transition:margin-left .4s}\r
+.w3-modal{z-index:3;display:none;padding-top:100px;position:fixed;left:0;top:0;width:100%;height:100%;overflow:auto;background-color:rgb(0,0,0);background-color:rgba(0,0,0,0.4)}\r
+.w3-modal-content{margin:auto;background-color:#fff;position:relative;padding:0;outline:0;width:600px}\r
+.w3-bar{width:100%;overflow:hidden}.w3-center .w3-bar{display:inline-block;width:auto}\r
+.w3-bar .w3-bar-item{padding:8px 16px;float:left;width:auto;border:none;display:block}\r
+.w3-bar .w3-dropdown-hover,.w3-bar .w3-dropdown-click{position:static;float:left}\r
+.w3-bar .w3-button{white-space:normal}\r
+.w3-bar-block .w3-bar-item{width:100%;display:block;padding:8px 16px;text-align:left;border:none;white-space:normal;float:none}\r
+.w3-bar-block.w3-center .w3-bar-item{text-align:center}.w3-block{display:block;width:100%}\r
+.w3-responsive{display:block;overflow-x:auto}\r
+.w3-container:after,.w3-container:before,.w3-panel:after,.w3-panel:before,.w3-row:after,.w3-row:before,.w3-row-padding:after,.w3-row-padding:before,\r
+.w3-cell-row:before,.w3-cell-row:after,.w3-clear:after,.w3-clear:before,.w3-bar:before,.w3-bar:after{content:"";display:table;clear:both}\r
+.w3-col,.w3-half,.w3-third,.w3-twothird,.w3-threequarter,.w3-quarter{float:left;width:100%}\r
+.w3-col.s1{width:8.33333%}.w3-col.s2{width:16.66666%}.w3-col.s3{width:24.99999%}.w3-col.s4{width:33.33333%}\r
+.w3-col.s5{width:41.66666%}.w3-col.s6{width:49.99999%}.w3-col.s7{width:58.33333%}.w3-col.s8{width:66.66666%}\r
+.w3-col.s9{width:74.99999%}.w3-col.s10{width:83.33333%}.w3-col.s11{width:91.66666%}.w3-col.s12{width:99.99999%}\r
+@media (min-width:601px){.w3-col.m1{width:8.33333%}.w3-col.m2{width:16.66666%}.w3-col.m3,.w3-quarter{width:24.99999%}.w3-col.m4,.w3-third{width:33.33333%}\r
+.w3-col.m5{width:41.66666%}.w3-col.m6,.w3-half{width:49.99999%}.w3-col.m7{width:58.33333%}.w3-col.m8,.w3-twothird{width:66.66666%}\r
+.w3-col.m9,.w3-threequarter{width:74.99999%}.w3-col.m10{width:83.33333%}.w3-col.m11{width:91.66666%}.w3-col.m12{width:99.99999%}}\r
+@media (min-width:993px){.w3-col.l1{width:8.33333%}.w3-col.l2{width:16.66666%}.w3-col.l3{width:24.99999%}.w3-col.l4{width:33.33333%}\r
+.w3-col.l5{width:41.66666%}.w3-col.l6{width:49.99999%}.w3-col.l7{width:58.33333%}.w3-col.l8{width:66.66666%}\r
+.w3-col.l9{width:74.99999%}.w3-col.l10{width:83.33333%}.w3-col.l11{width:91.66666%}.w3-col.l12{width:99.99999%}}\r
+.w3-content{max-width:980px;margin:auto}.w3-rest{overflow:hidden}\r
+.w3-cell-row{display:table;width:100%}.w3-cell{display:table-cell}\r
+.w3-cell-top{vertical-align:top}.w3-cell-middle{vertical-align:middle}.w3-cell-bottom{vertical-align:bottom}\r
+.w3-hide{display:none!important}.w3-show-block,.w3-show{display:block!important}.w3-show-inline-block{display:inline-block!important}\r
+@media (max-width:600px){.w3-modal-content{margin:0 10px;width:auto!important}.w3-modal{padding-top:30px}\r
+.w3-dropdown-hover.w3-mobile .w3-dropdown-content,.w3-dropdown-click.w3-mobile .w3-dropdown-content{position:relative} \r
+.w3-hide-small{display:none!important}.w3-mobile{display:block;width:100%!important}.w3-bar-item.w3-mobile,.w3-dropdown-hover.w3-mobile,.w3-dropdown-click.w3-mobile{text-align:center}\r
+.w3-dropdown-hover.w3-mobile,.w3-dropdown-hover.w3-mobile .w3-btn,.w3-dropdown-hover.w3-mobile .w3-button,.w3-dropdown-click.w3-mobile,.w3-dropdown-click.w3-mobile .w3-btn,.w3-dropdown-click.w3-mobile .w3-button{width:100%}}\r
+@media (max-width:768px){.w3-modal-content{width:500px}.w3-modal{padding-top:50px}}\r
+@media (min-width:993px){.w3-modal-content{width:900px}.w3-hide-large{display:none!important}.w3-sidebar.w3-collapse{display:block!important}}\r
+@media (max-width:992px) and (min-width:601px){.w3-hide-medium{display:none!important}}\r
+@media (max-width:992px){.w3-sidebar.w3-collapse{display:none}.w3-main{margin-left:0!important;margin-right:0!important}}\r
+.w3-top,.w3-bottom{position:fixed;width:100%;z-index:1}.w3-top{top:0}.w3-bottom{bottom:0}\r
+.w3-overlay{position:fixed;display:none;width:100%;height:100%;top:0;left:0;right:0;bottom:0;background-color:rgba(0,0,0,0.5);z-index:2}\r
+.w3-display-topleft{position:absolute;left:0;top:0}.w3-display-topright{position:absolute;right:0;top:0}\r
+.w3-display-bottomleft{position:absolute;left:0;bottom:0}.w3-display-bottomright{position:absolute;right:0;bottom:0}\r
+.w3-display-middle{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%)}\r
+.w3-display-left{position:absolute;top:50%;left:0%;transform:translate(0%,-50%);-ms-transform:translate(-0%,-50%)}\r
+.w3-display-right{position:absolute;top:50%;right:0%;transform:translate(0%,-50%);-ms-transform:translate(0%,-50%)}\r
+.w3-display-topmiddle{position:absolute;left:50%;top:0;transform:translate(-50%,0%);-ms-transform:translate(-50%,0%)}\r
+.w3-display-bottommiddle{position:absolute;left:50%;bottom:0;transform:translate(-50%,0%);-ms-transform:translate(-50%,0%)}\r
+.w3-display-container:hover .w3-display-hover{display:block}.w3-display-container:hover span.w3-display-hover{display:inline-block}.w3-display-hover{display:none}\r
+.w3-display-position{position:absolute}\r
+.w3-circle{border-radius:50%}\r
+.w3-round-small{border-radius:2px}.w3-round,.w3-round-medium{border-radius:4px}.w3-round-large{border-radius:8px}.w3-round-xlarge{border-radius:16px}.w3-round-xxlarge{border-radius:32px}\r
+.w3-row-padding,.w3-row-padding>.w3-half,.w3-row-padding>.w3-third,.w3-row-padding>.w3-twothird,.w3-row-padding>.w3-threequarter,.w3-row-padding>.w3-quarter,.w3-row-padding>.w3-col{padding:0 8px}\r
+.w3-container,.w3-panel{padding:0.01em 16px}.w3-panel{margin-top:16px;margin-bottom:16px}\r
+.w3-code,.w3-codespan{font-family:Consolas,"courier new";font-size:16px}\r
+.w3-code{width:auto;background-color:#fff;padding:8px 12px;border-left:4px solid #4CAF50;word-wrap:break-word}\r
+.w3-codespan{color:crimson;background-color:#f1f1f1;padding-left:4px;padding-right:4px;font-size:110%}\r
+.w3-card,.w3-card-2{box-shadow:0 2px 5px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12)}\r
+.w3-card-4,.w3-hover-shadow:hover{box-shadow:0 4px 10px 0 rgba(0,0,0,0.2),0 4px 20px 0 rgba(0,0,0,0.19)}\r
+.w3-spin{animation:w3-spin 2s infinite linear}@keyframes w3-spin{0%{transform:rotate(0deg)}100%{transform:rotate(359deg)}}\r
+.w3-animate-fading{animation:fading 10s infinite}@keyframes fading{0%{opacity:0}50%{opacity:1}100%{opacity:0}}\r
+.w3-animate-opacity{animation:opac 0.8s}@keyframes opac{from{opacity:0} to{opacity:1}}\r
+.w3-animate-top{position:relative;animation:animatetop 0.4s}@keyframes animatetop{from{top:-300px;opacity:0} to{top:0;opacity:1}}\r
+.w3-animate-left{position:relative;animation:animateleft 0.4s}@keyframes animateleft{from{left:-300px;opacity:0} to{left:0;opacity:1}}\r
+.w3-animate-right{position:relative;animation:animateright 0.4s}@keyframes animateright{from{right:-300px;opacity:0} to{right:0;opacity:1}}\r
+.w3-animate-bottom{position:relative;animation:animatebottom 0.4s}@keyframes animatebottom{from{bottom:-300px;opacity:0} to{bottom:0;opacity:1}}\r
+.w3-animate-zoom {animation:animatezoom 0.6s}@keyframes animatezoom{from{transform:scale(0)} to{transform:scale(1)}}\r
+.w3-animate-input{transition:width 0.4s ease-in-out}.w3-animate-input:focus{width:100%!important}\r
+.w3-opacity,.w3-hover-opacity:hover{opacity:0.60}.w3-opacity-off,.w3-hover-opacity-off:hover{opacity:1}\r
+.w3-opacity-max{opacity:0.25}.w3-opacity-min{opacity:0.75}\r
+.w3-greyscale-max,.w3-grayscale-max,.w3-hover-greyscale:hover,.w3-hover-grayscale:hover{filter:grayscale(100%)}\r
+.w3-greyscale,.w3-grayscale{filter:grayscale(75%)}.w3-greyscale-min,.w3-grayscale-min{filter:grayscale(50%)}\r
+.w3-sepia{filter:sepia(75%)}.w3-sepia-max,.w3-hover-sepia:hover{filter:sepia(100%)}.w3-sepia-min{filter:sepia(50%)}\r
+.w3-tiny{font-size:10px!important}.w3-small{font-size:12px!important}.w3-medium{font-size:15px!important}.w3-large{font-size:18px!important}\r
+.w3-xlarge{font-size:24px!important}.w3-xxlarge{font-size:36px!important}.w3-xxxlarge{font-size:48px!important}.w3-jumbo{font-size:64px!important}\r
+.w3-left-align{text-align:left!important}.w3-right-align{text-align:right!important}.w3-justify{text-align:justify!important}.w3-center{text-align:center!important}\r
+.w3-border-0{border:0!important}.w3-border{border:1px solid #ccc!important}\r
+.w3-border-top{border-top:1px solid #ccc!important}.w3-border-bottom{border-bottom:1px solid #ccc!important}\r
+.w3-border-left{border-left:1px solid #ccc!important}.w3-border-right{border-right:1px solid #ccc!important}\r
+.w3-topbar{border-top:6px solid #ccc!important}.w3-bottombar{border-bottom:6px solid #ccc!important}\r
+.w3-leftbar{border-left:6px solid #ccc!important}.w3-rightbar{border-right:6px solid #ccc!important}\r
+.w3-section,.w3-code{margin-top:16px!important;margin-bottom:16px!important}\r
+.w3-margin{margin:16px!important}.w3-margin-top{margin-top:16px!important}.w3-margin-bottom{margin-bottom:16px!important}\r
+.w3-margin-left{margin-left:16px!important}.w3-margin-right{margin-right:16px!important}\r
+.w3-padding-small{padding:4px 8px!important}.w3-padding{padding:8px 16px!important}.w3-padding-large{padding:12px 24px!important}\r
+.w3-padding-16{padding-top:16px!important;padding-bottom:16px!important}.w3-padding-24{padding-top:24px!important;padding-bottom:24px!important}\r
+.w3-padding-32{padding-top:32px!important;padding-bottom:32px!important}.w3-padding-48{padding-top:48px!important;padding-bottom:48px!important}\r
+.w3-padding-64{padding-top:64px!important;padding-bottom:64px!important}\r
+.w3-left{float:left!important}.w3-right{float:right!important}\r
+.w3-button:hover{color:#000!important;background-color:#ccc!important}\r
+.w3-transparent,.w3-hover-none:hover{background-color:transparent!important}\r
+.w3-hover-none:hover{box-shadow:none!important}\r
+/* Colors */\r
+.w3-amber,.w3-hover-amber:hover{color:#000!important;background-color:#ffc107!important}\r
+.w3-aqua,.w3-hover-aqua:hover{color:#000!important;background-color:#00ffff!important}\r
+.w3-blue,.w3-hover-blue:hover{color:#fff!important;background-color:#2196F3!important}\r
+.w3-light-blue,.w3-hover-light-blue:hover{color:#000!important;background-color:#87CEEB!important}\r
+.w3-brown,.w3-hover-brown:hover{color:#fff!important;background-color:#795548!important}\r
+.w3-cyan,.w3-hover-cyan:hover{color:#000!important;background-color:#00bcd4!important}\r
+.w3-blue-grey,.w3-hover-blue-grey:hover,.w3-blue-gray,.w3-hover-blue-gray:hover{color:#fff!important;background-color:#607d8b!important}\r
+.w3-green,.w3-hover-green:hover{color:#fff!important;background-color:#4CAF50!important}\r
+.w3-light-green,.w3-hover-light-green:hover{color:#000!important;background-color:#8bc34a!important}\r
+.w3-indigo,.w3-hover-indigo:hover{color:#fff!important;background-color:#3f51b5!important}\r
+.w3-khaki,.w3-hover-khaki:hover{color:#000!important;background-color:#f0e68c!important}\r
+.w3-lime,.w3-hover-lime:hover{color:#000!important;background-color:#cddc39!important}\r
+.w3-orange,.w3-hover-orange:hover{color:#000!important;background-color:#ff9800!important}\r
+.w3-deep-orange,.w3-hover-deep-orange:hover{color:#fff!important;background-color:#ff5722!important}\r
+.w3-pink,.w3-hover-pink:hover{color:#fff!important;background-color:#e91e63!important}\r
+.w3-purple,.w3-hover-purple:hover{color:#fff!important;background-color:#9c27b0!important}\r
+.w3-deep-purple,.w3-hover-deep-purple:hover{color:#fff!important;background-color:#673ab7!important}\r
+.w3-red,.w3-hover-red:hover{color:#fff!important;background-color:#f44336!important}\r
+.w3-sand,.w3-hover-sand:hover{color:#000!important;background-color:#fdf5e6!important}\r
+.w3-teal,.w3-hover-teal:hover{color:#fff!important;background-color:#009688!important}\r
+.w3-yellow,.w3-hover-yellow:hover{color:#000!important;background-color:#ffeb3b!important}\r
+.w3-white,.w3-hover-white:hover{color:#000!important;background-color:#fff!important}\r
+.w3-black,.w3-hover-black:hover{color:#fff!important;background-color:#000!important}\r
+.w3-grey,.w3-hover-grey:hover,.w3-gray,.w3-hover-gray:hover{color:#000!important;background-color:#9e9e9e!important}\r
+.w3-light-grey,.w3-hover-light-grey:hover,.w3-light-gray,.w3-hover-light-gray:hover{color:#000!important;background-color:#f1f1f1!important}\r
+.w3-dark-grey,.w3-hover-dark-grey:hover,.w3-dark-gray,.w3-hover-dark-gray:hover{color:#fff!important;background-color:#616161!important}\r
+.w3-pale-red,.w3-hover-pale-red:hover{color:#000!important;background-color:#ffdddd!important}\r
+.w3-pale-green,.w3-hover-pale-green:hover{color:#000!important;background-color:#ddffdd!important}\r
+.w3-pale-yellow,.w3-hover-pale-yellow:hover{color:#000!important;background-color:#ffffcc!important}\r
+.w3-pale-blue,.w3-hover-pale-blue:hover{color:#000!important;background-color:#ddffff!important}\r
+.w3-text-amber,.w3-hover-text-amber:hover{color:#ffc107!important}\r
+.w3-text-aqua,.w3-hover-text-aqua:hover{color:#00ffff!important}\r
+.w3-text-blue,.w3-hover-text-blue:hover{color:#2196F3!important}\r
+.w3-text-light-blue,.w3-hover-text-light-blue:hover{color:#87CEEB!important}\r
+.w3-text-brown,.w3-hover-text-brown:hover{color:#795548!important}\r
+.w3-text-cyan,.w3-hover-text-cyan:hover{color:#00bcd4!important}\r
+.w3-text-blue-grey,.w3-hover-text-blue-grey:hover,.w3-text-blue-gray,.w3-hover-text-blue-gray:hover{color:#607d8b!important}\r
+.w3-text-green,.w3-hover-text-green:hover{color:#4CAF50!important}\r
+.w3-text-light-green,.w3-hover-text-light-green:hover{color:#8bc34a!important}\r
+.w3-text-indigo,.w3-hover-text-indigo:hover{color:#3f51b5!important}\r
+.w3-text-khaki,.w3-hover-text-khaki:hover{color:#b4aa50!important}\r
+.w3-text-lime,.w3-hover-text-lime:hover{color:#cddc39!important}\r
+.w3-text-orange,.w3-hover-text-orange:hover{color:#ff9800!important}\r
+.w3-text-deep-orange,.w3-hover-text-deep-orange:hover{color:#ff5722!important}\r
+.w3-text-pink,.w3-hover-text-pink:hover{color:#e91e63!important}\r
+.w3-text-purple,.w3-hover-text-purple:hover{color:#9c27b0!important}\r
+.w3-text-deep-purple,.w3-hover-text-deep-purple:hover{color:#673ab7!important}\r
+.w3-text-red,.w3-hover-text-red:hover{color:#f44336!important}\r
+.w3-text-sand,.w3-hover-text-sand:hover{color:#fdf5e6!important}\r
+.w3-text-teal,.w3-hover-text-teal:hover{color:#009688!important}\r
+.w3-text-yellow,.w3-hover-text-yellow:hover{color:#d2be0e!important}\r
+.w3-text-white,.w3-hover-text-white:hover{color:#fff!important}\r
+.w3-text-black,.w3-hover-text-black:hover{color:#000!important}\r
+.w3-text-grey,.w3-hover-text-grey:hover,.w3-text-gray,.w3-hover-text-gray:hover{color:#757575!important}\r
+.w3-text-light-grey,.w3-hover-text-light-grey:hover,.w3-text-light-gray,.w3-hover-text-light-gray:hover{color:#f1f1f1!important}\r
+.w3-text-dark-grey,.w3-hover-text-dark-grey:hover,.w3-text-dark-gray,.w3-hover-text-dark-gray:hover{color:#3a3a3a!important}\r
+.w3-border-amber,.w3-hover-border-amber:hover{border-color:#ffc107!important}\r
+.w3-border-aqua,.w3-hover-border-aqua:hover{border-color:#00ffff!important}\r
+.w3-border-blue,.w3-hover-border-blue:hover{border-color:#2196F3!important}\r
+.w3-border-light-blue,.w3-hover-border-light-blue:hover{border-color:#87CEEB!important}\r
+.w3-border-brown,.w3-hover-border-brown:hover{border-color:#795548!important}\r
+.w3-border-cyan,.w3-hover-border-cyan:hover{border-color:#00bcd4!important}\r
+.w3-border-blue-grey,.w3-hover-border-blue-grey:hover,.w3-border-blue-gray,.w3-hover-border-blue-gray:hover{border-color:#607d8b!important}\r
+.w3-border-green,.w3-hover-border-green:hover{border-color:#4CAF50!important}\r
+.w3-border-light-green,.w3-hover-border-light-green:hover{border-color:#8bc34a!important}\r
+.w3-border-indigo,.w3-hover-border-indigo:hover{border-color:#3f51b5!important}\r
+.w3-border-khaki,.w3-hover-border-khaki:hover{border-color:#f0e68c!important}\r
+.w3-border-lime,.w3-hover-border-lime:hover{border-color:#cddc39!important}\r
+.w3-border-orange,.w3-hover-border-orange:hover{border-color:#ff9800!important}\r
+.w3-border-deep-orange,.w3-hover-border-deep-orange:hover{border-color:#ff5722!important}\r
+.w3-border-pink,.w3-hover-border-pink:hover{border-color:#e91e63!important}\r
+.w3-border-purple,.w3-hover-border-purple:hover{border-color:#9c27b0!important}\r
+.w3-border-deep-purple,.w3-hover-border-deep-purple:hover{border-color:#673ab7!important}\r
+.w3-border-red,.w3-hover-border-red:hover{border-color:#f44336!important}\r
+.w3-border-sand,.w3-hover-border-sand:hover{border-color:#fdf5e6!important}\r
+.w3-border-teal,.w3-hover-border-teal:hover{border-color:#009688!important}\r
+.w3-border-yellow,.w3-hover-border-yellow:hover{border-color:#ffeb3b!important}\r
+.w3-border-white,.w3-hover-border-white:hover{border-color:#fff!important}\r
+.w3-border-black,.w3-hover-border-black:hover{border-color:#000!important}\r
+.w3-border-grey,.w3-hover-border-grey:hover,.w3-border-gray,.w3-hover-border-gray:hover{border-color:#9e9e9e!important}\r
+.w3-border-light-grey,.w3-hover-border-light-grey:hover,.w3-border-light-gray,.w3-hover-border-light-gray:hover{border-color:#f1f1f1!important}\r
+.w3-border-dark-grey,.w3-hover-border-dark-grey:hover,.w3-border-dark-gray,.w3-hover-border-dark-gray:hover{border-color:#616161!important}\r
+.w3-border-pale-red,.w3-hover-border-pale-red:hover{border-color:#ffe7e7!important}.w3-border-pale-green,.w3-hover-border-pale-green:hover{border-color:#e7ffe7!important}\r
+.w3-border-pale-yellow,.w3-hover-border-pale-yellow:hover{border-color:#ffffcc!important}.w3-border-pale-blue,.w3-hover-border-pale-blue:hover{border-color:#e7ffff!important}
\ No newline at end of file
index 12c70b6..9fc6def 100644 (file)
@@ -25,6 +25,8 @@ struct mthread {
 
 
 // Renderer for one message in the threaded view
+// (This will probably work for the flat view too.)
+//
 void thread_render_one_message(struct ctdlsession *c, StrBuf *sj, long msgnum)
 {
        StrBuf *raw_msg = NULL;
@@ -32,67 +34,105 @@ void thread_render_one_message(struct ctdlsession *c, StrBuf *sj, long msgnum)
        char buf[1024];
        char content_transfer_encoding[1024] = { 0 };
        char content_type[1024] = { 0 };
+       char author[128] = { 0 };
+       char datetime[128] = { 0 } ;
 
        ctdl_printf(c, "MSG4 %ld", msgnum);
        ctdl_readline(c, buf, sizeof(buf));
-       if (buf[0] == '1') {
-               while ( (ctdl_readline(c, buf, sizeof(buf)) >= 0) && (strcmp(buf, "text")) && (strcmp(buf, "000")) ) {
-                       // citadel header parsing here
-                       if (!strncasecmp(buf, "from=", 5)) {
-                               StrBufAppendPrintf(sj, "<b>From %s</b><br>", &buf[5]);  // FIXME that was temporary
+       if (buf[0] != '1') {
+               StrBufAppendPrintf(sj, "<div>ERROR CONDITION FIXME WRITE A BOX</div>");
+               return;
+       }
+
+       while ( (ctdl_readline(c, buf, sizeof(buf)) >= 0) && (strcmp(buf, "text")) && (strcmp(buf, "000")) ) {
+               // citadel header parsing here
+               if (!strncasecmp(buf, "from=", 5)) {
+                       safestrncpy(author, &buf[5], sizeof author);
+               }
+               if (!strncasecmp(buf, "time=", 5)) {
+                       time_t tt;
+                       struct tm tm;
+                       tt = atol(&buf[5]);
+                       localtime_r(&tt, &tm);
+                       strftime(datetime, sizeof datetime, "%c", &tm);
+               }
+       }
+
+       if (!strcmp(buf, "text")) {
+               while ( (ctdl_readline(c, buf, sizeof(buf)) >= 0) && (strcmp(buf, "")) && (strcmp(buf, "000")) ) {
+                       // rfc822 header parsing here
+                       if (!strncasecmp(buf, "Content-transfer-encoding:", 26)) {
+                               strcpy(content_transfer_encoding, &buf[26]);
+                               striplt(content_transfer_encoding);
                        }
-                       if (!strncasecmp(buf, "part=", 5)) {
-                               //StrBufAppendPrintf(sj, "MIME part: %s<br>", &buf[5]); // FIXME that was temporary
+                       if (!strncasecmp(buf, "Content-type:", 13)) {
+                               strcpy(content_type, &buf[13]);
+                               striplt(content_type);
                        }
                }
-               if (!strcmp(buf, "text")) {
-                       while ( (ctdl_readline(c, buf, sizeof(buf)) >= 0) && (strcmp(buf, "")) && (strcmp(buf, "000")) ) {
-                               // rfc822 header parsing here
-                               if (!strncasecmp(buf, "Content-transfer-encoding:", 26)) {
-                                       strcpy(content_transfer_encoding, &buf[26]);
-                                       striplt(content_transfer_encoding);
-                               }
-                               if (!strncasecmp(buf, "Content-type:", 13)) {
-                                       strcpy(content_type, &buf[13]);
-                                       striplt(content_type);
-                                       //StrBufAppendPrintf(sj, "Content-type: %s<br>", content_type); // FIXME that was temporary
-                               }
-                       }
-                       raw_msg = ctdl_readtextmsg(c);
+               raw_msg = ctdl_readtextmsg(c);
+       }
+       else {
+               raw_msg = NULL;
+       }
+
+       // begin output
+
+       StrBufAppendPrintf(sj, "<div>");                                                // begin message wrapper
+       StrBufAppendPrintf(sj, "<div style=\"float:left;padding-right:2px\">");         // begin avatar FIXME move the style to a stylesheet
+       StrBufAppendPrintf(sj, "<i class=\"fa fa-user-circle fa-2x\"></i>");            // FIXME temporary avatar
+       StrBufAppendPrintf(sj, "</div>");                                               // end avatar
+       StrBufAppendPrintf(sj, "<div>");                                                // begin content
+       StrBufAppendPrintf(sj, "<div>");                                                // begin header
+       StrBufAppendPrintf(sj, "<span class=\"ctdl-username\"><a href=\"#\">%s</a></span>", author);    // FIXME link to user profile or whatever
+       StrBufAppendPrintf(sj, "<span class=\"ctdl-msgdate\">%s</span>", datetime);
+       StrBufAppendPrintf(sj, "</div>");                                               // end header
+       StrBufAppendPrintf(sj, "<div>");                                                // begin body
+
+       if (raw_msg) {
+
+               // These are the encodings we know how to handle.  Decode in-place.
+
+               if (!strcasecmp(content_transfer_encoding, "base64")) {
+                       StrBufDecodeBase64(raw_msg);
+               }
+               if (!strcasecmp(content_transfer_encoding, "quoted-printable")) {
+                       StrBufDecodeQP(raw_msg);
+               }
+
+               // At this point, raw_msg contains the decoded message.
+               // Now run through the renderers we have available.
+
+               if (!strncasecmp(content_type, "text/html", 9)) {
+                       sanitized_msg = html2html("UTF-8", 0, c->room, msgnum, raw_msg);
+               }
+               else if (!strncasecmp(content_type, "text/plain", 10)) {
+                       sanitized_msg = text2html("UTF-8", 0, c->room, msgnum, raw_msg);
+               }
+               else if (!strncasecmp(content_type, "text/x-citadel-variformat", 25)) {
+                       sanitized_msg = variformat2html(raw_msg);
                }
                else {
-                       raw_msg = NULL;
+                       sanitized_msg = NewStrBufPlain(HKEY("<i>No renderer for this content type</i><br>"));
                }
-               if (raw_msg) {
-                       if (!strcasecmp(content_transfer_encoding, "base64")) {
-                               StrBufDecodeBase64(raw_msg);
-                       }
-                       if (!strcasecmp(content_transfer_encoding, "quoted-printable")) {
-                               StrBufDecodeQP(raw_msg);
-                       }
-                       if (!strncasecmp(content_type, "text/html", 9)) {
-                               sanitized_msg = html2html("UTF-8", 0, c->room, msgnum, raw_msg);
-                       }
-                       else if (!strncasecmp(content_type, "text/plain", 10)) {
-                               sanitized_msg = text2html("UTF-8", 0, c->room, msgnum, raw_msg);
-                       }
-                       else if (!strncasecmp(content_type, "text/x-citadel-variformat", 25)) {
-                               sanitized_msg = variformat2html(raw_msg);
-                       }
-                       else {
-                               sanitized_msg = NewStrBufPlain(HKEY("<i>No renderer for this content type</i><br>"));
-                       }
-                       //sanitized_msg = NewStrBufDup(raw_msg);
-                       FreeStrBuf(&raw_msg);
-                       if (sanitized_msg) {
-                               StrBufAppendBuf(sj, sanitized_msg, 0);
-                               FreeStrBuf(&sanitized_msg);
-                       }
+               FreeStrBuf(&raw_msg);
+
+               // If sanitized_msg is not NULL, we have rendered the message and can output it.
+
+               if (sanitized_msg) {
+                       StrBufAppendBuf(sj, sanitized_msg, 0);
+                       FreeStrBuf(&sanitized_msg);
                }
        }
+
+       StrBufAppendPrintf(sj, "</div>");                                               // end body
+       StrBufAppendPrintf(sj, "</div>");                                               // end content
+       StrBufAppendPrintf(sj, "</div>");                                               // end wrapper
 }
 
 
+// Threaded view (recursive section)
+//
 void thread_o_print(struct ctdlsession *c, StrBuf *sj, struct mthread *m, int num_msgs, int where_parent_is, int nesting_level)
 {
        int i = 0;
@@ -103,14 +143,9 @@ void thread_o_print(struct ctdlsession *c, StrBuf *sj, struct mthread *m, int nu
                if (m[i].parent == where_parent_is) {
 
                        if (++num_printed == 1) {
-                               StrBufAppendPrintf(sj, "<ul>");
-                               StrBufAppendPrintf(sj, "<table style=\"border: 1px solid black;\"><tr><td>");   // temporary, for visualization
+                               StrBufAppendPrintf(sj, "<ul style=\"list-style-type: none;\">");
                        }
 
-                       //for (j=nesting_level; j>0; --j) {
-                               //StrBufAppendPrintf(sj, " ");
-                       //}
-
                        StrBufAppendPrintf(sj, "<li class=\"post\" id=\"post-%ld\">",  m[i].msgnum);
                        thread_render_one_message(c, sj, m[i].msgnum);
                        StrBufAppendPrintf(sj, "</li>\r\n");
@@ -121,13 +156,13 @@ void thread_o_print(struct ctdlsession *c, StrBuf *sj, struct mthread *m, int nu
        }
 
        if (num_printed > 0) {
-               StrBufAppendPrintf(sj, "</td></tr></table>");           // temporary, for visualization
                StrBufAppendPrintf(sj, "</ul>");
        }
 }
 
 
-
+// Threaded view (entry point)
+//
 void threaded_view(struct http_transaction *h, struct ctdlsession *c, char *which)
 {
        int num_msgs = 0;
@@ -202,7 +237,7 @@ void threaded_view(struct http_transaction *h, struct ctdlsession *c, char *whic
        ctdl_readline(c, buf, sizeof(buf));                     // Ignore the response
        thread_o_print(c, sj, m, num_msgs, 0, 0);               // Render threads recursively and recursively
 
-       // haha h0h0
+       // Garbage collection is for people who aren't smart enough to manage their own memory.
        if (num_msgs > 0) {
                free(m);
        }
@@ -216,5 +251,3 @@ void threaded_view(struct http_transaction *h, struct ctdlsession *c, char *whic
        h->response_body = SmashStrBuf(&sj);
        return;
 }
-
-