Fossil SCM
Begin adding style to the forum display.
Commit
8eccd9a221fd165563ad23c3e976171b8ae5c0b6f26274dd2e587bcb3220a4cc
Parent
7da12996859b46c…
2 files changed
+11
+47
-22
+11
| --- src/default_css.txt | ||
| +++ src/default_css.txt | ||
| @@ -676,5 +676,16 @@ | ||
| 676 | 676 | } |
| 677 | 677 | .debug { |
| 678 | 678 | background-color: #ffc; |
| 679 | 679 | border: 2px solid #ff0; |
| 680 | 680 | } |
| 681 | +div.forumEdit { | |
| 682 | + border: 1px solid black; | |
| 683 | + padding-left: 1ex; | |
| 684 | + padding-right: 1ex; | |
| 685 | +} | |
| 686 | +div.forumHier, div.forumTime { | |
| 687 | + border: 1px solid black; | |
| 688 | + padding-left: 1ex; | |
| 689 | + padding-right: 1ex; | |
| 690 | + margin-top: 1ex; | |
| 691 | +} | |
| 681 | 692 |
| --- src/default_css.txt | |
| +++ src/default_css.txt | |
| @@ -676,5 +676,16 @@ | |
| 676 | } |
| 677 | .debug { |
| 678 | background-color: #ffc; |
| 679 | border: 2px solid #ff0; |
| 680 | } |
| 681 |
| --- src/default_css.txt | |
| +++ src/default_css.txt | |
| @@ -676,5 +676,16 @@ | |
| 676 | } |
| 677 | .debug { |
| 678 | background-color: #ffc; |
| 679 | border: 2px solid #ff0; |
| 680 | } |
| 681 | div.forumEdit { |
| 682 | border: 1px solid black; |
| 683 | padding-left: 1ex; |
| 684 | padding-right: 1ex; |
| 685 | } |
| 686 | div.forumHier, div.forumTime { |
| 687 | border: 1px solid black; |
| 688 | padding-left: 1ex; |
| 689 | padding-right: 1ex; |
| 690 | margin-top: 1ex; |
| 691 | } |
| 692 |
+47
-22
| --- src/forum.c | ||
| +++ src/forum.c | ||
| @@ -61,17 +61,19 @@ | ||
| 61 | 61 | fossil_free(pEntry); |
| 62 | 62 | } |
| 63 | 63 | fossil_free(pThread); |
| 64 | 64 | } |
| 65 | 65 | |
| 66 | +#if 0 /* not used */ | |
| 66 | 67 | /* |
| 67 | 68 | ** Search a ForumEntry list forwards looking for the entry with fpid |
| 68 | 69 | */ |
| 69 | 70 | static ForumEntry *forumentry_forward(ForumEntry *p, int fpid){ |
| 70 | 71 | while( p && p->fpid!=fpid ) p = p->pNext; |
| 71 | 72 | return p; |
| 72 | 73 | } |
| 74 | +#endif | |
| 73 | 75 | |
| 74 | 76 | /* |
| 75 | 77 | ** Search backwards for a ForumEntry |
| 76 | 78 | */ |
| 77 | 79 | static ForumEntry *forumentry_backward(ForumEntry *p, int fpid){ |
| @@ -221,15 +223,18 @@ | ||
| 221 | 223 | |
| 222 | 224 | /* |
| 223 | 225 | ** Render a forum post for display |
| 224 | 226 | */ |
| 225 | 227 | void forum_render( |
| 226 | - const char *zTitle, | |
| 227 | - const char *zMimetype, | |
| 228 | - const char *zContent | |
| 228 | + const char *zTitle, /* The title. Might be NULL for no title */ | |
| 229 | + const char *zMimetype, /* Mimetype of the message */ | |
| 230 | + const char *zContent, /* Content of the message */ | |
| 231 | + const char *zClass /* Put in a <div> if not NULL */ | |
| 229 | 232 | ){ |
| 230 | - @ <div style='border: 1px solid black;padding: 1ex;'> | |
| 233 | + if( zClass ){ | |
| 234 | + @ <div class='%s(zClass)'> | |
| 235 | + } | |
| 231 | 236 | if( zTitle ){ |
| 232 | 237 | if( zTitle[0] ){ |
| 233 | 238 | @ <h1>%h(zTitle)</h1> |
| 234 | 239 | }else{ |
| 235 | 240 | @ <h1><i>Deleted</i></h1> |
| @@ -242,19 +247,20 @@ | ||
| 242 | 247 | wiki_render_by_mimetype(&x, zMimetype); |
| 243 | 248 | blob_reset(&x); |
| 244 | 249 | }else{ |
| 245 | 250 | @ <i>Deleted</i> |
| 246 | 251 | } |
| 247 | - @ </div> | |
| 252 | + if( zClass ){ | |
| 253 | + @ </div> | |
| 254 | + } | |
| 248 | 255 | } |
| 249 | 256 | |
| 250 | 257 | /* |
| 251 | 258 | ** Display all posts in a forum thread in chronological order |
| 252 | 259 | */ |
| 253 | 260 | static void forum_display_chronological(int froot, int target){ |
| 254 | 261 | Stmt q; |
| 255 | - int i = 0; | |
| 256 | 262 | db_prepare(&q, |
| 257 | 263 | "SELECT fpid, fprev, firt, uuid, datetime(fmtime,'unixepoch')\n" |
| 258 | 264 | " FROM forumpost, blob\n" |
| 259 | 265 | " WHERE froot=%d AND rid=fpid\n" |
| 260 | 266 | " ORDER BY fmtime", froot); |
| @@ -264,14 +270,11 @@ | ||
| 264 | 270 | int firt = db_column_int(&q, 2); |
| 265 | 271 | const char *zUuid = db_column_text(&q, 3); |
| 266 | 272 | const char *zDate = db_column_text(&q, 4); |
| 267 | 273 | Manifest *pPost = manifest_get(fpid, CFTYPE_FORUM, 0); |
| 268 | 274 | if( pPost==0 ) continue; |
| 269 | - if( i>0 ){ | |
| 270 | - @ <hr> | |
| 271 | - } | |
| 272 | - i++; | |
| 275 | + @ <div id="forum%d(fpid)" class="forumTime"> | |
| 273 | 276 | if( pPost->zThreadTitle ){ |
| 274 | 277 | @ <h1>%h(pPost->zThreadTitle)</h1> |
| 275 | 278 | } |
| 276 | 279 | @ <p>By %h(pPost->zUser) on %h(zDate) (%d(fpid)) |
| 277 | 280 | if( fprev ){ |
| @@ -282,11 +285,11 @@ | ||
| 282 | 285 | } |
| 283 | 286 | if( g.perm.Debug ){ |
| 284 | 287 | @ <span class="debug">\ |
| 285 | 288 | @ <a href="%R/artifact/%h(zUuid)">artifact</a></span> |
| 286 | 289 | } |
| 287 | - forum_render(0, pPost->zMimetype, pPost->zWiki); | |
| 290 | + forum_render(0, pPost->zMimetype, pPost->zWiki, 0); | |
| 288 | 291 | if( g.perm.WrForum ){ |
| 289 | 292 | int sameUser = login_is_individual() |
| 290 | 293 | && fossil_strcmp(pPost->zUser, g.zLogin)==0; |
| 291 | 294 | int isPrivate = content_is_private(fpid); |
| 292 | 295 | @ <p><form action="%R/forumedit" method="POST"> |
| @@ -310,29 +313,35 @@ | ||
| 310 | 313 | @ <input type="submit" name="reject" value="Delete"> |
| 311 | 314 | } |
| 312 | 315 | @ </form></p> |
| 313 | 316 | } |
| 314 | 317 | manifest_destroy(pPost); |
| 318 | + @ </div> | |
| 315 | 319 | } |
| 316 | 320 | db_finalize(&q); |
| 317 | 321 | } |
| 318 | 322 | |
| 319 | 323 | /* |
| 320 | 324 | ** Display all messages in a forumthread with indentation. |
| 321 | 325 | */ |
| 322 | -static void forum_display(int froot, int target){ | |
| 326 | +static int forum_display_hierarchical(int froot, int target){ | |
| 323 | 327 | ForumThread *pThread; |
| 324 | 328 | ForumEntry *p; |
| 325 | 329 | Manifest *pPost; |
| 326 | 330 | int fpid; |
| 327 | 331 | char *zDate; |
| 328 | 332 | char *zUuid; |
| 329 | 333 | |
| 330 | 334 | pThread = forumthread_create(froot); |
| 331 | 335 | for(p=pThread->pDisplay; p; p=p->pDisplay){ |
| 332 | - @ <div style='margin-left: %d((p->nIndent-1)*3)ex;'> | |
| 333 | 336 | fpid = p->pLeaf ? p->pLeaf->fpid : p->fpid; |
| 337 | + if( p->nIndent==1 ){ | |
| 338 | + @ <div id='forum(%d(fpid)' class='forumHierRoot'> | |
| 339 | + }else{ | |
| 340 | + @ <div id='forum%d(fpid)' class='forumHier' \ | |
| 341 | + @ style='margin-left: %d((p->nIndent-1)*3)ex;'> | |
| 342 | + } | |
| 334 | 343 | pPost = manifest_get(fpid, CFTYPE_FORUM, 0); |
| 335 | 344 | if( pPost==0 ) continue; |
| 336 | 345 | if( pPost->zThreadTitle ){ |
| 337 | 346 | @ <h1>%h(pPost->zThreadTitle)</h1> |
| 338 | 347 | } |
| @@ -342,11 +351,11 @@ | ||
| 342 | 351 | zUuid = rid_to_uuid(fpid); |
| 343 | 352 | if( g.perm.Debug ){ |
| 344 | 353 | @ <span class="debug">\ |
| 345 | 354 | @ <a href="%R/artifact/%h(zUuid)">artifact</a></span> |
| 346 | 355 | } |
| 347 | - forum_render(0, pPost->zMimetype, pPost->zWiki); | |
| 356 | + forum_render(0, pPost->zMimetype, pPost->zWiki, 0); | |
| 348 | 357 | if( g.perm.WrForum ){ |
| 349 | 358 | int sameUser = login_is_individual() |
| 350 | 359 | && fossil_strcmp(pPost->zUser, g.zLogin)==0; |
| 351 | 360 | int isPrivate = content_is_private(fpid); |
| 352 | 361 | @ <p><form action="%R/forumedit" method="POST"> |
| @@ -372,12 +381,19 @@ | ||
| 372 | 381 | @ </form></p> |
| 373 | 382 | } |
| 374 | 383 | manifest_destroy(pPost); |
| 375 | 384 | fossil_free(zUuid); |
| 376 | 385 | @ </div> |
| 386 | + } | |
| 387 | + for(p=pThread->pFirst; p; p=p->pNext){ | |
| 388 | + if( p->fpid==target ){ | |
| 389 | + if( p->pLeaf ) target = p->pLeaf->fpid; | |
| 390 | + break; | |
| 391 | + } | |
| 377 | 392 | } |
| 378 | 393 | forumthread_delete(pThread); |
| 394 | + return target; | |
| 379 | 395 | } |
| 380 | 396 | |
| 381 | 397 | /* |
| 382 | 398 | ** WEBPAGE: forumthread |
| 383 | 399 | ** |
| @@ -407,14 +423,21 @@ | ||
| 407 | 423 | froot = db_int(0, "SELECT froot FROM forumpost WHERE fpid=%d", fpid); |
| 408 | 424 | if( froot==0 ){ |
| 409 | 425 | webpage_error("Not a forum post: \"%s\"", zName); |
| 410 | 426 | } |
| 411 | 427 | if( P("t") ){ |
| 428 | + if( g.perm.Debug ){ | |
| 429 | + style_submenu_element("Hierarchical", "%R/forumthread/%s", zName); | |
| 430 | + } | |
| 412 | 431 | forum_display_chronological(froot, fpid); |
| 413 | 432 | }else{ |
| 414 | - forum_display(froot, fpid); | |
| 433 | + if( g.perm.Debug ){ | |
| 434 | + style_submenu_element("Chronological", "%R/forumthread/%s?t", zName); | |
| 435 | + } | |
| 436 | + fpid = forum_display_hierarchical(froot, fpid); | |
| 415 | 437 | } |
| 438 | + | |
| 416 | 439 | style_footer(); |
| 417 | 440 | } |
| 418 | 441 | |
| 419 | 442 | /* |
| 420 | 443 | ** Return true if a forum post should be moderated. |
| @@ -555,11 +578,11 @@ | ||
| 555 | 578 | if( P("submit") ){ |
| 556 | 579 | if( forum_post(zTitle, 0, 0, 0, zMimetype, zContent) ) return; |
| 557 | 580 | } |
| 558 | 581 | if( P("preview") ){ |
| 559 | 582 | @ <h1>Preview:</h1> |
| 560 | - forum_render(zTitle, zMimetype, zContent); | |
| 583 | + forum_render(zTitle, zMimetype, zContent, "forumEdit"); | |
| 561 | 584 | } |
| 562 | 585 | style_header("New Forum Thread"); |
| 563 | 586 | @ <form action="%R/%s(g.zPath)" method="POST"> |
| 564 | 587 | forum_entry_widget(zTitle, zMimetype, zContent); |
| 565 | 588 | @ <input type="submit" name="preview" value="Preview"> |
| @@ -644,13 +667,14 @@ | ||
| 644 | 667 | zMimetype = "text/x-fossil-wiki"; |
| 645 | 668 | zContent = ""; |
| 646 | 669 | if( pPost->zThreadTitle ) zTitle = ""; |
| 647 | 670 | style_header("Delete %s", zTitle ? "Post" : "Reply"); |
| 648 | 671 | @ <h1>Original Post:</h1> |
| 649 | - forum_render(pPost->zThreadTitle, pPost->zMimetype, pPost->zWiki); | |
| 672 | + forum_render(pPost->zThreadTitle, pPost->zMimetype, pPost->zWiki, | |
| 673 | + "forumEdit"); | |
| 650 | 674 | @ <h1>Change Into:</h1> |
| 651 | - forum_render(zTitle, zMimetype, zContent); | |
| 675 | + forum_render(zTitle, zMimetype, zContent,"forumEdit"); | |
| 652 | 676 | @ <form action="%R/forumedit" method="POST"> |
| 653 | 677 | @ <input type="hidden" name="fpid" value="%h(P("fpid"))"> |
| 654 | 678 | @ <input type="hidden" name="nullout" value="1"> |
| 655 | 679 | @ <input type="hidden" name="mimetype" value="%h(zMimetype)"> |
| 656 | 680 | @ <input type="hidden" name="content" value="%h(zContent)"> |
| @@ -667,14 +691,15 @@ | ||
| 667 | 691 | if( zTitle==0 && pPost->zThreadTitle!=0 ){ |
| 668 | 692 | zTitle = fossil_strdup(pPost->zThreadTitle); |
| 669 | 693 | } |
| 670 | 694 | style_header("Edit %s", zTitle ? "Post" : "Reply"); |
| 671 | 695 | @ <h1>Original Post:</h1> |
| 672 | - forum_render(pPost->zThreadTitle, pPost->zMimetype, pPost->zWiki); | |
| 696 | + forum_render(pPost->zThreadTitle, pPost->zMimetype, pPost->zWiki, | |
| 697 | + "forumEdit"); | |
| 673 | 698 | if( P("preview") ){ |
| 674 | 699 | @ <h1>Preview Of Editted Post:</h1> |
| 675 | - forum_render(zTitle, zMimetype, zContent); | |
| 700 | + forum_render(zTitle, zMimetype, zContent,"forumEdit"); | |
| 676 | 701 | } |
| 677 | 702 | @ <h1>Enter A Reply:</h1> |
| 678 | 703 | @ <form action="%R/forumedit" method="POST"> |
| 679 | 704 | @ <input type="hidden" name="fpid" value="%h(P("fpid"))"> |
| 680 | 705 | @ <input type="hidden" name="edit" value="1"> |
| @@ -683,14 +708,14 @@ | ||
| 683 | 708 | /* Reply */ |
| 684 | 709 | zMimetype = PD("mimetype","text/x-fossil-wiki"); |
| 685 | 710 | zContent = PDT("content",""); |
| 686 | 711 | style_header("Reply"); |
| 687 | 712 | @ <h1>Replying To:</h1> |
| 688 | - forum_render(0, pPost->zMimetype, pPost->zWiki); | |
| 713 | + forum_render(0, pPost->zMimetype, pPost->zWiki, "forumEdit"); | |
| 689 | 714 | if( P("preview") ){ |
| 690 | 715 | @ <h1>Preview:</h1> |
| 691 | - forum_render(0, zMimetype,zContent); | |
| 716 | + forum_render(0, zMimetype,zContent, "forumEdit"); | |
| 692 | 717 | } |
| 693 | 718 | @ <h1>Enter A Reply:</h1> |
| 694 | 719 | @ <form action="%R/forumedit" method="POST"> |
| 695 | 720 | @ <input type="hidden" name="fpid" value="%h(P("fpid"))"> |
| 696 | 721 | @ <input type="hidden" name="reply" value="1"> |
| 697 | 722 |
| --- src/forum.c | |
| +++ src/forum.c | |
| @@ -61,17 +61,19 @@ | |
| 61 | fossil_free(pEntry); |
| 62 | } |
| 63 | fossil_free(pThread); |
| 64 | } |
| 65 | |
| 66 | /* |
| 67 | ** Search a ForumEntry list forwards looking for the entry with fpid |
| 68 | */ |
| 69 | static ForumEntry *forumentry_forward(ForumEntry *p, int fpid){ |
| 70 | while( p && p->fpid!=fpid ) p = p->pNext; |
| 71 | return p; |
| 72 | } |
| 73 | |
| 74 | /* |
| 75 | ** Search backwards for a ForumEntry |
| 76 | */ |
| 77 | static ForumEntry *forumentry_backward(ForumEntry *p, int fpid){ |
| @@ -221,15 +223,18 @@ | |
| 221 | |
| 222 | /* |
| 223 | ** Render a forum post for display |
| 224 | */ |
| 225 | void forum_render( |
| 226 | const char *zTitle, |
| 227 | const char *zMimetype, |
| 228 | const char *zContent |
| 229 | ){ |
| 230 | @ <div style='border: 1px solid black;padding: 1ex;'> |
| 231 | if( zTitle ){ |
| 232 | if( zTitle[0] ){ |
| 233 | @ <h1>%h(zTitle)</h1> |
| 234 | }else{ |
| 235 | @ <h1><i>Deleted</i></h1> |
| @@ -242,19 +247,20 @@ | |
| 242 | wiki_render_by_mimetype(&x, zMimetype); |
| 243 | blob_reset(&x); |
| 244 | }else{ |
| 245 | @ <i>Deleted</i> |
| 246 | } |
| 247 | @ </div> |
| 248 | } |
| 249 | |
| 250 | /* |
| 251 | ** Display all posts in a forum thread in chronological order |
| 252 | */ |
| 253 | static void forum_display_chronological(int froot, int target){ |
| 254 | Stmt q; |
| 255 | int i = 0; |
| 256 | db_prepare(&q, |
| 257 | "SELECT fpid, fprev, firt, uuid, datetime(fmtime,'unixepoch')\n" |
| 258 | " FROM forumpost, blob\n" |
| 259 | " WHERE froot=%d AND rid=fpid\n" |
| 260 | " ORDER BY fmtime", froot); |
| @@ -264,14 +270,11 @@ | |
| 264 | int firt = db_column_int(&q, 2); |
| 265 | const char *zUuid = db_column_text(&q, 3); |
| 266 | const char *zDate = db_column_text(&q, 4); |
| 267 | Manifest *pPost = manifest_get(fpid, CFTYPE_FORUM, 0); |
| 268 | if( pPost==0 ) continue; |
| 269 | if( i>0 ){ |
| 270 | @ <hr> |
| 271 | } |
| 272 | i++; |
| 273 | if( pPost->zThreadTitle ){ |
| 274 | @ <h1>%h(pPost->zThreadTitle)</h1> |
| 275 | } |
| 276 | @ <p>By %h(pPost->zUser) on %h(zDate) (%d(fpid)) |
| 277 | if( fprev ){ |
| @@ -282,11 +285,11 @@ | |
| 282 | } |
| 283 | if( g.perm.Debug ){ |
| 284 | @ <span class="debug">\ |
| 285 | @ <a href="%R/artifact/%h(zUuid)">artifact</a></span> |
| 286 | } |
| 287 | forum_render(0, pPost->zMimetype, pPost->zWiki); |
| 288 | if( g.perm.WrForum ){ |
| 289 | int sameUser = login_is_individual() |
| 290 | && fossil_strcmp(pPost->zUser, g.zLogin)==0; |
| 291 | int isPrivate = content_is_private(fpid); |
| 292 | @ <p><form action="%R/forumedit" method="POST"> |
| @@ -310,29 +313,35 @@ | |
| 310 | @ <input type="submit" name="reject" value="Delete"> |
| 311 | } |
| 312 | @ </form></p> |
| 313 | } |
| 314 | manifest_destroy(pPost); |
| 315 | } |
| 316 | db_finalize(&q); |
| 317 | } |
| 318 | |
| 319 | /* |
| 320 | ** Display all messages in a forumthread with indentation. |
| 321 | */ |
| 322 | static void forum_display(int froot, int target){ |
| 323 | ForumThread *pThread; |
| 324 | ForumEntry *p; |
| 325 | Manifest *pPost; |
| 326 | int fpid; |
| 327 | char *zDate; |
| 328 | char *zUuid; |
| 329 | |
| 330 | pThread = forumthread_create(froot); |
| 331 | for(p=pThread->pDisplay; p; p=p->pDisplay){ |
| 332 | @ <div style='margin-left: %d((p->nIndent-1)*3)ex;'> |
| 333 | fpid = p->pLeaf ? p->pLeaf->fpid : p->fpid; |
| 334 | pPost = manifest_get(fpid, CFTYPE_FORUM, 0); |
| 335 | if( pPost==0 ) continue; |
| 336 | if( pPost->zThreadTitle ){ |
| 337 | @ <h1>%h(pPost->zThreadTitle)</h1> |
| 338 | } |
| @@ -342,11 +351,11 @@ | |
| 342 | zUuid = rid_to_uuid(fpid); |
| 343 | if( g.perm.Debug ){ |
| 344 | @ <span class="debug">\ |
| 345 | @ <a href="%R/artifact/%h(zUuid)">artifact</a></span> |
| 346 | } |
| 347 | forum_render(0, pPost->zMimetype, pPost->zWiki); |
| 348 | if( g.perm.WrForum ){ |
| 349 | int sameUser = login_is_individual() |
| 350 | && fossil_strcmp(pPost->zUser, g.zLogin)==0; |
| 351 | int isPrivate = content_is_private(fpid); |
| 352 | @ <p><form action="%R/forumedit" method="POST"> |
| @@ -372,12 +381,19 @@ | |
| 372 | @ </form></p> |
| 373 | } |
| 374 | manifest_destroy(pPost); |
| 375 | fossil_free(zUuid); |
| 376 | @ </div> |
| 377 | } |
| 378 | forumthread_delete(pThread); |
| 379 | } |
| 380 | |
| 381 | /* |
| 382 | ** WEBPAGE: forumthread |
| 383 | ** |
| @@ -407,14 +423,21 @@ | |
| 407 | froot = db_int(0, "SELECT froot FROM forumpost WHERE fpid=%d", fpid); |
| 408 | if( froot==0 ){ |
| 409 | webpage_error("Not a forum post: \"%s\"", zName); |
| 410 | } |
| 411 | if( P("t") ){ |
| 412 | forum_display_chronological(froot, fpid); |
| 413 | }else{ |
| 414 | forum_display(froot, fpid); |
| 415 | } |
| 416 | style_footer(); |
| 417 | } |
| 418 | |
| 419 | /* |
| 420 | ** Return true if a forum post should be moderated. |
| @@ -555,11 +578,11 @@ | |
| 555 | if( P("submit") ){ |
| 556 | if( forum_post(zTitle, 0, 0, 0, zMimetype, zContent) ) return; |
| 557 | } |
| 558 | if( P("preview") ){ |
| 559 | @ <h1>Preview:</h1> |
| 560 | forum_render(zTitle, zMimetype, zContent); |
| 561 | } |
| 562 | style_header("New Forum Thread"); |
| 563 | @ <form action="%R/%s(g.zPath)" method="POST"> |
| 564 | forum_entry_widget(zTitle, zMimetype, zContent); |
| 565 | @ <input type="submit" name="preview" value="Preview"> |
| @@ -644,13 +667,14 @@ | |
| 644 | zMimetype = "text/x-fossil-wiki"; |
| 645 | zContent = ""; |
| 646 | if( pPost->zThreadTitle ) zTitle = ""; |
| 647 | style_header("Delete %s", zTitle ? "Post" : "Reply"); |
| 648 | @ <h1>Original Post:</h1> |
| 649 | forum_render(pPost->zThreadTitle, pPost->zMimetype, pPost->zWiki); |
| 650 | @ <h1>Change Into:</h1> |
| 651 | forum_render(zTitle, zMimetype, zContent); |
| 652 | @ <form action="%R/forumedit" method="POST"> |
| 653 | @ <input type="hidden" name="fpid" value="%h(P("fpid"))"> |
| 654 | @ <input type="hidden" name="nullout" value="1"> |
| 655 | @ <input type="hidden" name="mimetype" value="%h(zMimetype)"> |
| 656 | @ <input type="hidden" name="content" value="%h(zContent)"> |
| @@ -667,14 +691,15 @@ | |
| 667 | if( zTitle==0 && pPost->zThreadTitle!=0 ){ |
| 668 | zTitle = fossil_strdup(pPost->zThreadTitle); |
| 669 | } |
| 670 | style_header("Edit %s", zTitle ? "Post" : "Reply"); |
| 671 | @ <h1>Original Post:</h1> |
| 672 | forum_render(pPost->zThreadTitle, pPost->zMimetype, pPost->zWiki); |
| 673 | if( P("preview") ){ |
| 674 | @ <h1>Preview Of Editted Post:</h1> |
| 675 | forum_render(zTitle, zMimetype, zContent); |
| 676 | } |
| 677 | @ <h1>Enter A Reply:</h1> |
| 678 | @ <form action="%R/forumedit" method="POST"> |
| 679 | @ <input type="hidden" name="fpid" value="%h(P("fpid"))"> |
| 680 | @ <input type="hidden" name="edit" value="1"> |
| @@ -683,14 +708,14 @@ | |
| 683 | /* Reply */ |
| 684 | zMimetype = PD("mimetype","text/x-fossil-wiki"); |
| 685 | zContent = PDT("content",""); |
| 686 | style_header("Reply"); |
| 687 | @ <h1>Replying To:</h1> |
| 688 | forum_render(0, pPost->zMimetype, pPost->zWiki); |
| 689 | if( P("preview") ){ |
| 690 | @ <h1>Preview:</h1> |
| 691 | forum_render(0, zMimetype,zContent); |
| 692 | } |
| 693 | @ <h1>Enter A Reply:</h1> |
| 694 | @ <form action="%R/forumedit" method="POST"> |
| 695 | @ <input type="hidden" name="fpid" value="%h(P("fpid"))"> |
| 696 | @ <input type="hidden" name="reply" value="1"> |
| 697 |
| --- src/forum.c | |
| +++ src/forum.c | |
| @@ -61,17 +61,19 @@ | |
| 61 | fossil_free(pEntry); |
| 62 | } |
| 63 | fossil_free(pThread); |
| 64 | } |
| 65 | |
| 66 | #if 0 /* not used */ |
| 67 | /* |
| 68 | ** Search a ForumEntry list forwards looking for the entry with fpid |
| 69 | */ |
| 70 | static ForumEntry *forumentry_forward(ForumEntry *p, int fpid){ |
| 71 | while( p && p->fpid!=fpid ) p = p->pNext; |
| 72 | return p; |
| 73 | } |
| 74 | #endif |
| 75 | |
| 76 | /* |
| 77 | ** Search backwards for a ForumEntry |
| 78 | */ |
| 79 | static ForumEntry *forumentry_backward(ForumEntry *p, int fpid){ |
| @@ -221,15 +223,18 @@ | |
| 223 | |
| 224 | /* |
| 225 | ** Render a forum post for display |
| 226 | */ |
| 227 | void forum_render( |
| 228 | const char *zTitle, /* The title. Might be NULL for no title */ |
| 229 | const char *zMimetype, /* Mimetype of the message */ |
| 230 | const char *zContent, /* Content of the message */ |
| 231 | const char *zClass /* Put in a <div> if not NULL */ |
| 232 | ){ |
| 233 | if( zClass ){ |
| 234 | @ <div class='%s(zClass)'> |
| 235 | } |
| 236 | if( zTitle ){ |
| 237 | if( zTitle[0] ){ |
| 238 | @ <h1>%h(zTitle)</h1> |
| 239 | }else{ |
| 240 | @ <h1><i>Deleted</i></h1> |
| @@ -242,19 +247,20 @@ | |
| 247 | wiki_render_by_mimetype(&x, zMimetype); |
| 248 | blob_reset(&x); |
| 249 | }else{ |
| 250 | @ <i>Deleted</i> |
| 251 | } |
| 252 | if( zClass ){ |
| 253 | @ </div> |
| 254 | } |
| 255 | } |
| 256 | |
| 257 | /* |
| 258 | ** Display all posts in a forum thread in chronological order |
| 259 | */ |
| 260 | static void forum_display_chronological(int froot, int target){ |
| 261 | Stmt q; |
| 262 | db_prepare(&q, |
| 263 | "SELECT fpid, fprev, firt, uuid, datetime(fmtime,'unixepoch')\n" |
| 264 | " FROM forumpost, blob\n" |
| 265 | " WHERE froot=%d AND rid=fpid\n" |
| 266 | " ORDER BY fmtime", froot); |
| @@ -264,14 +270,11 @@ | |
| 270 | int firt = db_column_int(&q, 2); |
| 271 | const char *zUuid = db_column_text(&q, 3); |
| 272 | const char *zDate = db_column_text(&q, 4); |
| 273 | Manifest *pPost = manifest_get(fpid, CFTYPE_FORUM, 0); |
| 274 | if( pPost==0 ) continue; |
| 275 | @ <div id="forum%d(fpid)" class="forumTime"> |
| 276 | if( pPost->zThreadTitle ){ |
| 277 | @ <h1>%h(pPost->zThreadTitle)</h1> |
| 278 | } |
| 279 | @ <p>By %h(pPost->zUser) on %h(zDate) (%d(fpid)) |
| 280 | if( fprev ){ |
| @@ -282,11 +285,11 @@ | |
| 285 | } |
| 286 | if( g.perm.Debug ){ |
| 287 | @ <span class="debug">\ |
| 288 | @ <a href="%R/artifact/%h(zUuid)">artifact</a></span> |
| 289 | } |
| 290 | forum_render(0, pPost->zMimetype, pPost->zWiki, 0); |
| 291 | if( g.perm.WrForum ){ |
| 292 | int sameUser = login_is_individual() |
| 293 | && fossil_strcmp(pPost->zUser, g.zLogin)==0; |
| 294 | int isPrivate = content_is_private(fpid); |
| 295 | @ <p><form action="%R/forumedit" method="POST"> |
| @@ -310,29 +313,35 @@ | |
| 313 | @ <input type="submit" name="reject" value="Delete"> |
| 314 | } |
| 315 | @ </form></p> |
| 316 | } |
| 317 | manifest_destroy(pPost); |
| 318 | @ </div> |
| 319 | } |
| 320 | db_finalize(&q); |
| 321 | } |
| 322 | |
| 323 | /* |
| 324 | ** Display all messages in a forumthread with indentation. |
| 325 | */ |
| 326 | static int forum_display_hierarchical(int froot, int target){ |
| 327 | ForumThread *pThread; |
| 328 | ForumEntry *p; |
| 329 | Manifest *pPost; |
| 330 | int fpid; |
| 331 | char *zDate; |
| 332 | char *zUuid; |
| 333 | |
| 334 | pThread = forumthread_create(froot); |
| 335 | for(p=pThread->pDisplay; p; p=p->pDisplay){ |
| 336 | fpid = p->pLeaf ? p->pLeaf->fpid : p->fpid; |
| 337 | if( p->nIndent==1 ){ |
| 338 | @ <div id='forum(%d(fpid)' class='forumHierRoot'> |
| 339 | }else{ |
| 340 | @ <div id='forum%d(fpid)' class='forumHier' \ |
| 341 | @ style='margin-left: %d((p->nIndent-1)*3)ex;'> |
| 342 | } |
| 343 | pPost = manifest_get(fpid, CFTYPE_FORUM, 0); |
| 344 | if( pPost==0 ) continue; |
| 345 | if( pPost->zThreadTitle ){ |
| 346 | @ <h1>%h(pPost->zThreadTitle)</h1> |
| 347 | } |
| @@ -342,11 +351,11 @@ | |
| 351 | zUuid = rid_to_uuid(fpid); |
| 352 | if( g.perm.Debug ){ |
| 353 | @ <span class="debug">\ |
| 354 | @ <a href="%R/artifact/%h(zUuid)">artifact</a></span> |
| 355 | } |
| 356 | forum_render(0, pPost->zMimetype, pPost->zWiki, 0); |
| 357 | if( g.perm.WrForum ){ |
| 358 | int sameUser = login_is_individual() |
| 359 | && fossil_strcmp(pPost->zUser, g.zLogin)==0; |
| 360 | int isPrivate = content_is_private(fpid); |
| 361 | @ <p><form action="%R/forumedit" method="POST"> |
| @@ -372,12 +381,19 @@ | |
| 381 | @ </form></p> |
| 382 | } |
| 383 | manifest_destroy(pPost); |
| 384 | fossil_free(zUuid); |
| 385 | @ </div> |
| 386 | } |
| 387 | for(p=pThread->pFirst; p; p=p->pNext){ |
| 388 | if( p->fpid==target ){ |
| 389 | if( p->pLeaf ) target = p->pLeaf->fpid; |
| 390 | break; |
| 391 | } |
| 392 | } |
| 393 | forumthread_delete(pThread); |
| 394 | return target; |
| 395 | } |
| 396 | |
| 397 | /* |
| 398 | ** WEBPAGE: forumthread |
| 399 | ** |
| @@ -407,14 +423,21 @@ | |
| 423 | froot = db_int(0, "SELECT froot FROM forumpost WHERE fpid=%d", fpid); |
| 424 | if( froot==0 ){ |
| 425 | webpage_error("Not a forum post: \"%s\"", zName); |
| 426 | } |
| 427 | if( P("t") ){ |
| 428 | if( g.perm.Debug ){ |
| 429 | style_submenu_element("Hierarchical", "%R/forumthread/%s", zName); |
| 430 | } |
| 431 | forum_display_chronological(froot, fpid); |
| 432 | }else{ |
| 433 | if( g.perm.Debug ){ |
| 434 | style_submenu_element("Chronological", "%R/forumthread/%s?t", zName); |
| 435 | } |
| 436 | fpid = forum_display_hierarchical(froot, fpid); |
| 437 | } |
| 438 | |
| 439 | style_footer(); |
| 440 | } |
| 441 | |
| 442 | /* |
| 443 | ** Return true if a forum post should be moderated. |
| @@ -555,11 +578,11 @@ | |
| 578 | if( P("submit") ){ |
| 579 | if( forum_post(zTitle, 0, 0, 0, zMimetype, zContent) ) return; |
| 580 | } |
| 581 | if( P("preview") ){ |
| 582 | @ <h1>Preview:</h1> |
| 583 | forum_render(zTitle, zMimetype, zContent, "forumEdit"); |
| 584 | } |
| 585 | style_header("New Forum Thread"); |
| 586 | @ <form action="%R/%s(g.zPath)" method="POST"> |
| 587 | forum_entry_widget(zTitle, zMimetype, zContent); |
| 588 | @ <input type="submit" name="preview" value="Preview"> |
| @@ -644,13 +667,14 @@ | |
| 667 | zMimetype = "text/x-fossil-wiki"; |
| 668 | zContent = ""; |
| 669 | if( pPost->zThreadTitle ) zTitle = ""; |
| 670 | style_header("Delete %s", zTitle ? "Post" : "Reply"); |
| 671 | @ <h1>Original Post:</h1> |
| 672 | forum_render(pPost->zThreadTitle, pPost->zMimetype, pPost->zWiki, |
| 673 | "forumEdit"); |
| 674 | @ <h1>Change Into:</h1> |
| 675 | forum_render(zTitle, zMimetype, zContent,"forumEdit"); |
| 676 | @ <form action="%R/forumedit" method="POST"> |
| 677 | @ <input type="hidden" name="fpid" value="%h(P("fpid"))"> |
| 678 | @ <input type="hidden" name="nullout" value="1"> |
| 679 | @ <input type="hidden" name="mimetype" value="%h(zMimetype)"> |
| 680 | @ <input type="hidden" name="content" value="%h(zContent)"> |
| @@ -667,14 +691,15 @@ | |
| 691 | if( zTitle==0 && pPost->zThreadTitle!=0 ){ |
| 692 | zTitle = fossil_strdup(pPost->zThreadTitle); |
| 693 | } |
| 694 | style_header("Edit %s", zTitle ? "Post" : "Reply"); |
| 695 | @ <h1>Original Post:</h1> |
| 696 | forum_render(pPost->zThreadTitle, pPost->zMimetype, pPost->zWiki, |
| 697 | "forumEdit"); |
| 698 | if( P("preview") ){ |
| 699 | @ <h1>Preview Of Editted Post:</h1> |
| 700 | forum_render(zTitle, zMimetype, zContent,"forumEdit"); |
| 701 | } |
| 702 | @ <h1>Enter A Reply:</h1> |
| 703 | @ <form action="%R/forumedit" method="POST"> |
| 704 | @ <input type="hidden" name="fpid" value="%h(P("fpid"))"> |
| 705 | @ <input type="hidden" name="edit" value="1"> |
| @@ -683,14 +708,14 @@ | |
| 708 | /* Reply */ |
| 709 | zMimetype = PD("mimetype","text/x-fossil-wiki"); |
| 710 | zContent = PDT("content",""); |
| 711 | style_header("Reply"); |
| 712 | @ <h1>Replying To:</h1> |
| 713 | forum_render(0, pPost->zMimetype, pPost->zWiki, "forumEdit"); |
| 714 | if( P("preview") ){ |
| 715 | @ <h1>Preview:</h1> |
| 716 | forum_render(0, zMimetype,zContent, "forumEdit"); |
| 717 | } |
| 718 | @ <h1>Enter A Reply:</h1> |
| 719 | @ <form action="%R/forumedit" method="POST"> |
| 720 | @ <input type="hidden" name="fpid" value="%h(P("fpid"))"> |
| 721 | @ <input type="hidden" name="reply" value="1"> |
| 722 |