Fossil SCM
Separately show original and edited user/date
Commit
39a550c8d56c67baf8a7f51352f3c5c679bfe6ffa54208fe6a47ae187e0b388c
Parent
1bfa36867dd94b0…
1 file changed
+39
-22
+39
-22
| --- src/forum.c | ||
| +++ src/forum.c | ||
| @@ -403,19 +403,26 @@ | ||
| 403 | 403 | char *zQuery /* Common query string */ |
| 404 | 404 | ){ |
| 405 | 405 | char *zDisplayName; /* The display name */ |
| 406 | 406 | char *zDate; /* The time/date string */ |
| 407 | 407 | char *zHist; /* History query string */ |
| 408 | - Manifest *pManifest; /* Manifest comprising the current post */ | |
| 408 | + Manifest *pOriginal; /* Original post artifact */ | |
| 409 | + Manifest *pRevised; /* Revised post artifact (may be same as pOriginal) */ | |
| 409 | 410 | int bPrivate; /* True for posts awaiting moderation */ |
| 410 | 411 | int bSameUser; /* True if author is also the reader */ |
| 411 | 412 | int iIndent; /* Indent level */ |
| 412 | 413 | const char *zMimetype;/* Formatting MIME type */ |
| 413 | 414 | |
| 414 | - /* Get the manifest for the post. Abort if not found (e.g. shunned). */ | |
| 415 | - pManifest = manifest_get(p->fpid, CFTYPE_FORUM, 0); | |
| 416 | - if( !pManifest ) return; | |
| 415 | + /* Get the original and revised artifacts for the post. Abort if either is | |
| 416 | + * not found (e.g. shunned). */ | |
| 417 | + if( p->pEditHead ){ | |
| 418 | + pOriginal = manifest_get(p->pEditHead->fpid, CFTYPE_FORUM, 0); | |
| 419 | + pRevised = manifest_get(p->fpid, CFTYPE_FORUM, 0); | |
| 420 | + }else{ | |
| 421 | + pOriginal = pRevised = manifest_get(p->fpid, CFTYPE_FORUM, 0); | |
| 422 | + } | |
| 423 | + if( !pOriginal || !pRevised ) return; | |
| 417 | 424 | |
| 418 | 425 | /* When not in raw mode, create the border around the post. */ |
| 419 | 426 | if( !bRaw ){ |
| 420 | 427 | /* Open the <div> enclosing the post. Set the class string to mark the post |
| 421 | 428 | ** as selected and/or obsolete. */ |
| @@ -427,24 +434,30 @@ | ||
| 427 | 434 | @ style='margin-left: %d(iIndent*iIndentScale)ex' |
| 428 | 435 | } |
| 429 | 436 | @ > |
| 430 | 437 | |
| 431 | 438 | /* If this is the first post (or an edit thereof), emit the thread title. */ |
| 432 | - if( pManifest->zThreadTitle ){ | |
| 433 | - @ <h1>%h(pManifest->zThreadTitle)</h1> | |
| 439 | + if( pRevised->zThreadTitle ){ | |
| 440 | + @ <h1>%h(pRevised->zThreadTitle)</h1> | |
| 434 | 441 | } |
| 435 | 442 | |
| 436 | 443 | /* Emit the serial number, revision number, author, and date. */ |
| 437 | - zDisplayName = display_name_from_login(pManifest->zUser); | |
| 438 | - zDate = db_text(0, "SELECT datetime(%.17g)", pManifest->rDate); | |
| 444 | + zDisplayName = display_name_from_login(pOriginal->zUser); | |
| 445 | + zDate = db_text(0, "SELECT datetime(%.17g)", pOriginal->rDate); | |
| 439 | 446 | @ <h3 class='forumPostHdr'>(%d(p->sid)\ |
| 440 | 447 | if( p->nEdit ){ |
| 441 | 448 | @ .%.*d(fossil_num_digits(p->nEdit))(p->rev)\ |
| 442 | 449 | } |
| 443 | 450 | @ ) By %h(zDisplayName) on %h(zDate) |
| 444 | 451 | fossil_free(zDisplayName); |
| 445 | 452 | fossil_free(zDate); |
| 453 | + | |
| 454 | + /* If debugging is enabled, link to the artifact page. */ | |
| 455 | + if( g.perm.Debug ){ | |
| 456 | + @ <span class="debug">\ | |
| 457 | + @ <a href="%R/artifact/%h(p->zUuid)">(artifact-%d(p->fpid))</a></span> | |
| 458 | + } | |
| 446 | 459 | |
| 447 | 460 | /* If this is an edit, refer back to the old version. Be sure "hist" is in |
| 448 | 461 | ** the query string so the old version will actually be shown. */ |
| 449 | 462 | if( p->pEditPrev ){ |
| 450 | 463 | zHist = bHist ? "" : "&hist"; |
| @@ -451,16 +464,10 @@ | ||
| 451 | 464 | @ edit of \ |
| 452 | 465 | @ %z(href("%R/forumpost/%S?%s%s",p->pEditPrev->zUuid,zQuery,zHist))\ |
| 453 | 466 | @ %d(p->sid).%.*d(fossil_num_digits(p->nEdit))(p->pEditPrev->rev)</a> |
| 454 | 467 | } |
| 455 | 468 | |
| 456 | - /* If debugging is enabled, link to the artifact page. */ | |
| 457 | - if( g.perm.Debug ){ | |
| 458 | - @ <span class="debug">\ | |
| 459 | - @ <a href="%R/artifact/%h(p->zUuid)">(artifact-%d(p->fpid))</a></span> | |
| 460 | - } | |
| 461 | - | |
| 462 | 469 | /* If this is a reply, refer back to the parent post. */ |
| 463 | 470 | if( p->pIrt ){ |
| 464 | 471 | @ in reply to %z(href("%R/forumpost/%S?%s",p->pIrt->zUuid,zQuery))\ |
| 465 | 472 | @ %d(p->pIrt->sid)\ |
| 466 | 473 | if( p->pIrt->nEdit ){ |
| @@ -483,28 +490,37 @@ | ||
| 483 | 490 | |
| 484 | 491 | /* Provide a link to the raw source code. */ |
| 485 | 492 | if( !bUnf ){ |
| 486 | 493 | @ %z(href("%R/forumpost/%S?raw",p->zUuid))[source]</a> |
| 487 | 494 | } |
| 495 | + | |
| 496 | + /* If this is an edit, identify the editor and date. */ | |
| 497 | + if( p->pEditPrev ){ | |
| 498 | + zDisplayName = display_name_from_login(pRevised->zUser); | |
| 499 | + zDate = db_text(0, "SELECT datetime(%.17g)", pRevised->rDate); | |
| 500 | + @ <br>Edited by %h(zDisplayName) on %h(zDate) | |
| 501 | + fossil_free(zDisplayName); | |
| 502 | + fossil_free(zDate); | |
| 503 | + } | |
| 488 | 504 | @ </h3> |
| 489 | 505 | } |
| 490 | 506 | |
| 491 | 507 | /* Check if this post is approved, also if it's by the current user. */ |
| 492 | 508 | bPrivate = content_is_private(p->fpid); |
| 493 | 509 | bSameUser = login_is_individual() |
| 494 | - && fossil_strcmp(pManifest->zUser, g.zLogin)==0; | |
| 510 | + && fossil_strcmp(pOriginal->zUser, g.zLogin)==0; | |
| 495 | 511 | |
| 496 | 512 | /* Render the post if the user is able to see it. */ |
| 497 | 513 | if( bPrivate && !g.perm.ModForum && !bSameUser ){ |
| 498 | 514 | @ <p><span class="modpending">Awaiting Moderator Approval</span></p> |
| 499 | 515 | }else{ |
| 500 | 516 | if( bRaw || bUnf || p->pEditTail ){ |
| 501 | 517 | zMimetype = "text/plain"; |
| 502 | 518 | }else{ |
| 503 | - zMimetype = pManifest->zMimetype; | |
| 519 | + zMimetype = pRevised->zMimetype; | |
| 504 | 520 | } |
| 505 | - forum_render(0, zMimetype, pManifest->zWiki, 0, !bRaw); | |
| 521 | + forum_render(0, zMimetype, pRevised->zWiki, 0, !bRaw); | |
| 506 | 522 | } |
| 507 | 523 | |
| 508 | 524 | /* When not in raw mode, finish creating the border around the post. */ |
| 509 | 525 | if( !bRaw ){ |
| 510 | 526 | /* If the user is able to write to the forum and if this post has not been |
| @@ -523,16 +539,16 @@ | ||
| 523 | 539 | /* Allow moderators to approve or reject pending posts. Also allow |
| 524 | 540 | ** forum supervisors to mark non-special users as trusted and therefore |
| 525 | 541 | ** able to post unmoderated. */ |
| 526 | 542 | @ <input type="submit" name="approve" value="Approve"> |
| 527 | 543 | @ <input type="submit" name="reject" value="Reject"> |
| 528 | - if( g.perm.AdminForum && !login_is_special(pManifest->zUser) ){ | |
| 544 | + if( g.perm.AdminForum && !login_is_special(pOriginal->zUser) ){ | |
| 529 | 545 | @ <br><label><input type="checkbox" name="trust"> |
| 530 | - @ Trust user "%h(pManifest->zUser)" so that future posts by \ | |
| 531 | - @ "%h(pManifest->zUser)" do not require moderation. | |
| 546 | + @ Trust user "%h(pOriginal->zUser)" so that future posts by \ | |
| 547 | + @ "%h(pOriginal->zUser)" do not require moderation. | |
| 532 | 548 | @ </label> |
| 533 | - @ <input type="hidden" name="trustuser" value="%h(pManifest->zUser)"> | |
| 549 | + @ <input type="hidden" name="trustuser" value="%h(pOriginal->zUser)"> | |
| 534 | 550 | } |
| 535 | 551 | }else if( bSameUser ){ |
| 536 | 552 | /* Allow users to delete (reject) their own pending posts. */ |
| 537 | 553 | @ <input type="submit" name="reject" value="Delete"> |
| 538 | 554 | } |
| @@ -540,11 +556,12 @@ | ||
| 540 | 556 | } |
| 541 | 557 | @ </div> |
| 542 | 558 | } |
| 543 | 559 | |
| 544 | 560 | /* Clean up. */ |
| 545 | - manifest_destroy(pManifest); | |
| 561 | + if( pRevised!=pOriginal ) manifest_destroy(pRevised); | |
| 562 | + manifest_destroy(pOriginal); | |
| 546 | 563 | } |
| 547 | 564 | |
| 548 | 565 | /* |
| 549 | 566 | ** Possible display modes for forum_display_thread(). |
| 550 | 567 | */ |
| 551 | 568 |
| --- src/forum.c | |
| +++ src/forum.c | |
| @@ -403,19 +403,26 @@ | |
| 403 | char *zQuery /* Common query string */ |
| 404 | ){ |
| 405 | char *zDisplayName; /* The display name */ |
| 406 | char *zDate; /* The time/date string */ |
| 407 | char *zHist; /* History query string */ |
| 408 | Manifest *pManifest; /* Manifest comprising the current post */ |
| 409 | int bPrivate; /* True for posts awaiting moderation */ |
| 410 | int bSameUser; /* True if author is also the reader */ |
| 411 | int iIndent; /* Indent level */ |
| 412 | const char *zMimetype;/* Formatting MIME type */ |
| 413 | |
| 414 | /* Get the manifest for the post. Abort if not found (e.g. shunned). */ |
| 415 | pManifest = manifest_get(p->fpid, CFTYPE_FORUM, 0); |
| 416 | if( !pManifest ) return; |
| 417 | |
| 418 | /* When not in raw mode, create the border around the post. */ |
| 419 | if( !bRaw ){ |
| 420 | /* Open the <div> enclosing the post. Set the class string to mark the post |
| 421 | ** as selected and/or obsolete. */ |
| @@ -427,24 +434,30 @@ | |
| 427 | @ style='margin-left: %d(iIndent*iIndentScale)ex' |
| 428 | } |
| 429 | @ > |
| 430 | |
| 431 | /* If this is the first post (or an edit thereof), emit the thread title. */ |
| 432 | if( pManifest->zThreadTitle ){ |
| 433 | @ <h1>%h(pManifest->zThreadTitle)</h1> |
| 434 | } |
| 435 | |
| 436 | /* Emit the serial number, revision number, author, and date. */ |
| 437 | zDisplayName = display_name_from_login(pManifest->zUser); |
| 438 | zDate = db_text(0, "SELECT datetime(%.17g)", pManifest->rDate); |
| 439 | @ <h3 class='forumPostHdr'>(%d(p->sid)\ |
| 440 | if( p->nEdit ){ |
| 441 | @ .%.*d(fossil_num_digits(p->nEdit))(p->rev)\ |
| 442 | } |
| 443 | @ ) By %h(zDisplayName) on %h(zDate) |
| 444 | fossil_free(zDisplayName); |
| 445 | fossil_free(zDate); |
| 446 | |
| 447 | /* If this is an edit, refer back to the old version. Be sure "hist" is in |
| 448 | ** the query string so the old version will actually be shown. */ |
| 449 | if( p->pEditPrev ){ |
| 450 | zHist = bHist ? "" : "&hist"; |
| @@ -451,16 +464,10 @@ | |
| 451 | @ edit of \ |
| 452 | @ %z(href("%R/forumpost/%S?%s%s",p->pEditPrev->zUuid,zQuery,zHist))\ |
| 453 | @ %d(p->sid).%.*d(fossil_num_digits(p->nEdit))(p->pEditPrev->rev)</a> |
| 454 | } |
| 455 | |
| 456 | /* If debugging is enabled, link to the artifact page. */ |
| 457 | if( g.perm.Debug ){ |
| 458 | @ <span class="debug">\ |
| 459 | @ <a href="%R/artifact/%h(p->zUuid)">(artifact-%d(p->fpid))</a></span> |
| 460 | } |
| 461 | |
| 462 | /* If this is a reply, refer back to the parent post. */ |
| 463 | if( p->pIrt ){ |
| 464 | @ in reply to %z(href("%R/forumpost/%S?%s",p->pIrt->zUuid,zQuery))\ |
| 465 | @ %d(p->pIrt->sid)\ |
| 466 | if( p->pIrt->nEdit ){ |
| @@ -483,28 +490,37 @@ | |
| 483 | |
| 484 | /* Provide a link to the raw source code. */ |
| 485 | if( !bUnf ){ |
| 486 | @ %z(href("%R/forumpost/%S?raw",p->zUuid))[source]</a> |
| 487 | } |
| 488 | @ </h3> |
| 489 | } |
| 490 | |
| 491 | /* Check if this post is approved, also if it's by the current user. */ |
| 492 | bPrivate = content_is_private(p->fpid); |
| 493 | bSameUser = login_is_individual() |
| 494 | && fossil_strcmp(pManifest->zUser, g.zLogin)==0; |
| 495 | |
| 496 | /* Render the post if the user is able to see it. */ |
| 497 | if( bPrivate && !g.perm.ModForum && !bSameUser ){ |
| 498 | @ <p><span class="modpending">Awaiting Moderator Approval</span></p> |
| 499 | }else{ |
| 500 | if( bRaw || bUnf || p->pEditTail ){ |
| 501 | zMimetype = "text/plain"; |
| 502 | }else{ |
| 503 | zMimetype = pManifest->zMimetype; |
| 504 | } |
| 505 | forum_render(0, zMimetype, pManifest->zWiki, 0, !bRaw); |
| 506 | } |
| 507 | |
| 508 | /* When not in raw mode, finish creating the border around the post. */ |
| 509 | if( !bRaw ){ |
| 510 | /* If the user is able to write to the forum and if this post has not been |
| @@ -523,16 +539,16 @@ | |
| 523 | /* Allow moderators to approve or reject pending posts. Also allow |
| 524 | ** forum supervisors to mark non-special users as trusted and therefore |
| 525 | ** able to post unmoderated. */ |
| 526 | @ <input type="submit" name="approve" value="Approve"> |
| 527 | @ <input type="submit" name="reject" value="Reject"> |
| 528 | if( g.perm.AdminForum && !login_is_special(pManifest->zUser) ){ |
| 529 | @ <br><label><input type="checkbox" name="trust"> |
| 530 | @ Trust user "%h(pManifest->zUser)" so that future posts by \ |
| 531 | @ "%h(pManifest->zUser)" do not require moderation. |
| 532 | @ </label> |
| 533 | @ <input type="hidden" name="trustuser" value="%h(pManifest->zUser)"> |
| 534 | } |
| 535 | }else if( bSameUser ){ |
| 536 | /* Allow users to delete (reject) their own pending posts. */ |
| 537 | @ <input type="submit" name="reject" value="Delete"> |
| 538 | } |
| @@ -540,11 +556,12 @@ | |
| 540 | } |
| 541 | @ </div> |
| 542 | } |
| 543 | |
| 544 | /* Clean up. */ |
| 545 | manifest_destroy(pManifest); |
| 546 | } |
| 547 | |
| 548 | /* |
| 549 | ** Possible display modes for forum_display_thread(). |
| 550 | */ |
| 551 |
| --- src/forum.c | |
| +++ src/forum.c | |
| @@ -403,19 +403,26 @@ | |
| 403 | char *zQuery /* Common query string */ |
| 404 | ){ |
| 405 | char *zDisplayName; /* The display name */ |
| 406 | char *zDate; /* The time/date string */ |
| 407 | char *zHist; /* History query string */ |
| 408 | Manifest *pOriginal; /* Original post artifact */ |
| 409 | Manifest *pRevised; /* Revised post artifact (may be same as pOriginal) */ |
| 410 | int bPrivate; /* True for posts awaiting moderation */ |
| 411 | int bSameUser; /* True if author is also the reader */ |
| 412 | int iIndent; /* Indent level */ |
| 413 | const char *zMimetype;/* Formatting MIME type */ |
| 414 | |
| 415 | /* Get the original and revised artifacts for the post. Abort if either is |
| 416 | * not found (e.g. shunned). */ |
| 417 | if( p->pEditHead ){ |
| 418 | pOriginal = manifest_get(p->pEditHead->fpid, CFTYPE_FORUM, 0); |
| 419 | pRevised = manifest_get(p->fpid, CFTYPE_FORUM, 0); |
| 420 | }else{ |
| 421 | pOriginal = pRevised = manifest_get(p->fpid, CFTYPE_FORUM, 0); |
| 422 | } |
| 423 | if( !pOriginal || !pRevised ) return; |
| 424 | |
| 425 | /* When not in raw mode, create the border around the post. */ |
| 426 | if( !bRaw ){ |
| 427 | /* Open the <div> enclosing the post. Set the class string to mark the post |
| 428 | ** as selected and/or obsolete. */ |
| @@ -427,24 +434,30 @@ | |
| 434 | @ style='margin-left: %d(iIndent*iIndentScale)ex' |
| 435 | } |
| 436 | @ > |
| 437 | |
| 438 | /* If this is the first post (or an edit thereof), emit the thread title. */ |
| 439 | if( pRevised->zThreadTitle ){ |
| 440 | @ <h1>%h(pRevised->zThreadTitle)</h1> |
| 441 | } |
| 442 | |
| 443 | /* Emit the serial number, revision number, author, and date. */ |
| 444 | zDisplayName = display_name_from_login(pOriginal->zUser); |
| 445 | zDate = db_text(0, "SELECT datetime(%.17g)", pOriginal->rDate); |
| 446 | @ <h3 class='forumPostHdr'>(%d(p->sid)\ |
| 447 | if( p->nEdit ){ |
| 448 | @ .%.*d(fossil_num_digits(p->nEdit))(p->rev)\ |
| 449 | } |
| 450 | @ ) By %h(zDisplayName) on %h(zDate) |
| 451 | fossil_free(zDisplayName); |
| 452 | fossil_free(zDate); |
| 453 | |
| 454 | /* If debugging is enabled, link to the artifact page. */ |
| 455 | if( g.perm.Debug ){ |
| 456 | @ <span class="debug">\ |
| 457 | @ <a href="%R/artifact/%h(p->zUuid)">(artifact-%d(p->fpid))</a></span> |
| 458 | } |
| 459 | |
| 460 | /* If this is an edit, refer back to the old version. Be sure "hist" is in |
| 461 | ** the query string so the old version will actually be shown. */ |
| 462 | if( p->pEditPrev ){ |
| 463 | zHist = bHist ? "" : "&hist"; |
| @@ -451,16 +464,10 @@ | |
| 464 | @ edit of \ |
| 465 | @ %z(href("%R/forumpost/%S?%s%s",p->pEditPrev->zUuid,zQuery,zHist))\ |
| 466 | @ %d(p->sid).%.*d(fossil_num_digits(p->nEdit))(p->pEditPrev->rev)</a> |
| 467 | } |
| 468 | |
| 469 | /* If this is a reply, refer back to the parent post. */ |
| 470 | if( p->pIrt ){ |
| 471 | @ in reply to %z(href("%R/forumpost/%S?%s",p->pIrt->zUuid,zQuery))\ |
| 472 | @ %d(p->pIrt->sid)\ |
| 473 | if( p->pIrt->nEdit ){ |
| @@ -483,28 +490,37 @@ | |
| 490 | |
| 491 | /* Provide a link to the raw source code. */ |
| 492 | if( !bUnf ){ |
| 493 | @ %z(href("%R/forumpost/%S?raw",p->zUuid))[source]</a> |
| 494 | } |
| 495 | |
| 496 | /* If this is an edit, identify the editor and date. */ |
| 497 | if( p->pEditPrev ){ |
| 498 | zDisplayName = display_name_from_login(pRevised->zUser); |
| 499 | zDate = db_text(0, "SELECT datetime(%.17g)", pRevised->rDate); |
| 500 | @ <br>Edited by %h(zDisplayName) on %h(zDate) |
| 501 | fossil_free(zDisplayName); |
| 502 | fossil_free(zDate); |
| 503 | } |
| 504 | @ </h3> |
| 505 | } |
| 506 | |
| 507 | /* Check if this post is approved, also if it's by the current user. */ |
| 508 | bPrivate = content_is_private(p->fpid); |
| 509 | bSameUser = login_is_individual() |
| 510 | && fossil_strcmp(pOriginal->zUser, g.zLogin)==0; |
| 511 | |
| 512 | /* Render the post if the user is able to see it. */ |
| 513 | if( bPrivate && !g.perm.ModForum && !bSameUser ){ |
| 514 | @ <p><span class="modpending">Awaiting Moderator Approval</span></p> |
| 515 | }else{ |
| 516 | if( bRaw || bUnf || p->pEditTail ){ |
| 517 | zMimetype = "text/plain"; |
| 518 | }else{ |
| 519 | zMimetype = pRevised->zMimetype; |
| 520 | } |
| 521 | forum_render(0, zMimetype, pRevised->zWiki, 0, !bRaw); |
| 522 | } |
| 523 | |
| 524 | /* When not in raw mode, finish creating the border around the post. */ |
| 525 | if( !bRaw ){ |
| 526 | /* If the user is able to write to the forum and if this post has not been |
| @@ -523,16 +539,16 @@ | |
| 539 | /* Allow moderators to approve or reject pending posts. Also allow |
| 540 | ** forum supervisors to mark non-special users as trusted and therefore |
| 541 | ** able to post unmoderated. */ |
| 542 | @ <input type="submit" name="approve" value="Approve"> |
| 543 | @ <input type="submit" name="reject" value="Reject"> |
| 544 | if( g.perm.AdminForum && !login_is_special(pOriginal->zUser) ){ |
| 545 | @ <br><label><input type="checkbox" name="trust"> |
| 546 | @ Trust user "%h(pOriginal->zUser)" so that future posts by \ |
| 547 | @ "%h(pOriginal->zUser)" do not require moderation. |
| 548 | @ </label> |
| 549 | @ <input type="hidden" name="trustuser" value="%h(pOriginal->zUser)"> |
| 550 | } |
| 551 | }else if( bSameUser ){ |
| 552 | /* Allow users to delete (reject) their own pending posts. */ |
| 553 | @ <input type="submit" name="reject" value="Delete"> |
| 554 | } |
| @@ -540,11 +556,12 @@ | |
| 556 | } |
| 557 | @ </div> |
| 558 | } |
| 559 | |
| 560 | /* Clean up. */ |
| 561 | if( pRevised!=pOriginal ) manifest_destroy(pRevised); |
| 562 | manifest_destroy(pOriginal); |
| 563 | } |
| 564 | |
| 565 | /* |
| 566 | ** Possible display modes for forum_display_thread(). |
| 567 | */ |
| 568 |