Fossil SCM

Add the /forum page with search and a list of recent threads.

drh 2018-07-31 04:08 forum-v2
Commit 05105248a1568220b61c85cbb271f9b08af570fa3f1f7e8b1a473b4bab92fa04
2 files changed +51 +14 -4
+51
--- src/forum.c
+++ src/forum.c
@@ -883,5 +883,56 @@
883883
@ </div>
884884
}
885885
@ </form>
886886
style_footer();
887887
}
888
+
889
+/*
890
+** WEBPAGE: forum
891
+**
892
+** The main page for the forum feature. Show a list of recent forum
893
+** threads. Also show a search box at the top if search is enabled,
894
+** and a button for creating a new thread, if enabled.
895
+*/
896
+void forum_main_page(void){
897
+ Stmt q;
898
+ int iLimit, iOfst;
899
+ login_check_credentials();
900
+ sqlite3_int64 iNow = time(NULL);
901
+ if( !g.perm.RdForum ){
902
+ login_needed(g.anon.RdForum);
903
+ return;
904
+ }
905
+ style_header("Forum");
906
+ if( g.perm.WrForum ){
907
+ style_submenu_element("New Message","%R/forumnew");
908
+ }
909
+ if( search_screen(SRCH_FORUM, 0) ){
910
+ style_submenu_element("Recent Threads","%R/forum");
911
+ style_footer();
912
+ return;
913
+ }
914
+ iLimit = 50;
915
+ iOfst = 0;
916
+ @ <h1>Recent Threads</h1>
917
+ @ <div class='fileage'><table width="100%%">
918
+ db_prepare(&q,
919
+ "SELECT julianday('now') - max(fmtime),"
920
+ " (SELECT uuid FROM blob WHERE rid=fpid),"
921
+ " (SELECT substr(comment,instr(comment,':')+2)"
922
+ " FROM event WHERE objid=fpid)"
923
+ " FROM forumpost"
924
+ " GROUP BY froot ORDER BY 1 LIMIT %d OFFSET %d",
925
+ iLimit, iOfst
926
+ );
927
+ while( db_step(&q)==SQLITE_ROW ){
928
+ char *zAge = human_readable_age(db_column_double(&q,0));
929
+ const char *zUuid = db_column_text(&q, 1);
930
+ const char *zTitle = db_column_text(&q, 2);
931
+ @ <tr><td>%h(zAge) ago</td>
932
+ @ <td>%z(href("%R/forumpost/%S",zUuid))%h(zTitle)</a>
933
+ @ </tr>
934
+ fossil_free(zAge);
935
+ }
936
+ @ </table></div>
937
+ style_footer();
938
+}
888939
--- src/forum.c
+++ src/forum.c
@@ -883,5 +883,56 @@
883 @ </div>
884 }
885 @ </form>
886 style_footer();
887 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
888
--- src/forum.c
+++ src/forum.c
@@ -883,5 +883,56 @@
883 @ </div>
884 }
885 @ </form>
886 style_footer();
887 }
888
889 /*
890 ** WEBPAGE: forum
891 **
892 ** The main page for the forum feature. Show a list of recent forum
893 ** threads. Also show a search box at the top if search is enabled,
894 ** and a button for creating a new thread, if enabled.
895 */
896 void forum_main_page(void){
897 Stmt q;
898 int iLimit, iOfst;
899 login_check_credentials();
900 sqlite3_int64 iNow = time(NULL);
901 if( !g.perm.RdForum ){
902 login_needed(g.anon.RdForum);
903 return;
904 }
905 style_header("Forum");
906 if( g.perm.WrForum ){
907 style_submenu_element("New Message","%R/forumnew");
908 }
909 if( search_screen(SRCH_FORUM, 0) ){
910 style_submenu_element("Recent Threads","%R/forum");
911 style_footer();
912 return;
913 }
914 iLimit = 50;
915 iOfst = 0;
916 @ <h1>Recent Threads</h1>
917 @ <div class='fileage'><table width="100%%">
918 db_prepare(&q,
919 "SELECT julianday('now') - max(fmtime),"
920 " (SELECT uuid FROM blob WHERE rid=fpid),"
921 " (SELECT substr(comment,instr(comment,':')+2)"
922 " FROM event WHERE objid=fpid)"
923 " FROM forumpost"
924 " GROUP BY froot ORDER BY 1 LIMIT %d OFFSET %d",
925 iLimit, iOfst
926 );
927 while( db_step(&q)==SQLITE_ROW ){
928 char *zAge = human_readable_age(db_column_double(&q,0));
929 const char *zUuid = db_column_text(&q, 1);
930 const char *zTitle = db_column_text(&q, 2);
931 @ <tr><td>%h(zAge) ago</td>
932 @ <td>%z(href("%R/forumpost/%S",zUuid))%h(zTitle)</a>
933 @ </tr>
934 fossil_free(zAge);
935 }
936 @ </table></div>
937 style_footer();
938 }
939
+14 -4
--- src/search.c
+++ src/search.c
@@ -1066,20 +1066,27 @@
10661066
**
10671067
** This routine automatically restricts srchFlag according to user
10681068
** permissions and the server configuration. The entry box is shown
10691069
** disabled if srchFlags is 0 after these restrictions are applied.
10701070
**
1071
-** If useYparam is true, then this routine also looks at the y= query
1072
-** parameter for further search restrictions.
1071
+** The mFlags value controls options:
1072
+**
1073
+** 0x01 If the y= query parameter is present, use it as an addition
1074
+** restriction what to search.
1075
+**
1076
+** 0x02 Show nothing if search is disabled.
1077
+**
1078
+** Return true if there are search results.
10731079
*/
1074
-void search_screen(unsigned srchFlags, int useYparam){
1080
+int search_screen(unsigned srchFlags, int mFlags){
10751081
const char *zType = 0;
10761082
const char *zClass = 0;
10771083
const char *zDisable1;
10781084
const char *zDisable2;
10791085
const char *zPattern;
10801086
int fDebug = PB("debug");
1087
+ int haveResult = 0;
10811088
srchFlags = search_restrict(srchFlags);
10821089
switch( srchFlags ){
10831090
case SRCH_CKIN: zType = " Check-ins"; zClass = "Ckin"; break;
10841091
case SRCH_DOC: zType = " Docs"; zClass = "Doc"; break;
10851092
case SRCH_TKT: zType = " Tickets"; zClass = "Tkt"; break;
@@ -1086,10 +1093,11 @@
10861093
case SRCH_WIKI: zType = " Wiki"; zClass = "Wiki"; break;
10871094
case SRCH_TECHNOTE: zType = " Tech Notes"; zClass = "Note"; break;
10881095
case SRCH_FORUM: zType = " Forum"; zClass = "Frm"; break;
10891096
}
10901097
if( srchFlags==0 ){
1098
+ if( mFlags & 0x02 ) return 0;
10911099
zDisable1 = " disabled";
10921100
zDisable2 = " disabled";
10931101
zPattern = "";
10941102
}else{
10951103
zDisable1 = ""; /* Was: " autofocus" */
@@ -1101,11 +1109,11 @@
11011109
@ <div class='searchForm searchForm%s(zClass)'>
11021110
}else{
11031111
@ <div class='searchForm'>
11041112
}
11051113
@ <input type="text" name="s" size="40" value="%h(zPattern)"%s(zDisable1)>
1106
- if( useYparam && (srchFlags & (srchFlags-1))!=0 && useYparam ){
1114
+ if( (mFlags & 0x01)!=0 && (srchFlags & (srchFlags-1))!=0 ){
11071115
static const struct { char *z; char *zNm; unsigned m; } aY[] = {
11081116
{ "all", "All", SRCH_ALL },
11091117
{ "c", "Check-ins", SRCH_CKIN },
11101118
{ "d", "Docs", SRCH_DOC },
11111119
{ "t", "Tickets", SRCH_TKT },
@@ -1146,11 +1154,13 @@
11461154
}
11471155
if( search_run_and_output(zPattern, srchFlags, fDebug)==0 ){
11481156
@ <p class='searchEmpty'>No matches for: <span>%h(zPattern)</span></p>
11491157
}
11501158
@ </div>
1159
+ haveResult = 1;
11511160
}
1161
+ return haveResult;
11521162
}
11531163
11541164
/*
11551165
** WEBPAGE: search
11561166
**
11571167
--- src/search.c
+++ src/search.c
@@ -1066,20 +1066,27 @@
1066 **
1067 ** This routine automatically restricts srchFlag according to user
1068 ** permissions and the server configuration. The entry box is shown
1069 ** disabled if srchFlags is 0 after these restrictions are applied.
1070 **
1071 ** If useYparam is true, then this routine also looks at the y= query
1072 ** parameter for further search restrictions.
 
 
 
 
 
 
1073 */
1074 void search_screen(unsigned srchFlags, int useYparam){
1075 const char *zType = 0;
1076 const char *zClass = 0;
1077 const char *zDisable1;
1078 const char *zDisable2;
1079 const char *zPattern;
1080 int fDebug = PB("debug");
 
1081 srchFlags = search_restrict(srchFlags);
1082 switch( srchFlags ){
1083 case SRCH_CKIN: zType = " Check-ins"; zClass = "Ckin"; break;
1084 case SRCH_DOC: zType = " Docs"; zClass = "Doc"; break;
1085 case SRCH_TKT: zType = " Tickets"; zClass = "Tkt"; break;
@@ -1086,10 +1093,11 @@
1086 case SRCH_WIKI: zType = " Wiki"; zClass = "Wiki"; break;
1087 case SRCH_TECHNOTE: zType = " Tech Notes"; zClass = "Note"; break;
1088 case SRCH_FORUM: zType = " Forum"; zClass = "Frm"; break;
1089 }
1090 if( srchFlags==0 ){
 
1091 zDisable1 = " disabled";
1092 zDisable2 = " disabled";
1093 zPattern = "";
1094 }else{
1095 zDisable1 = ""; /* Was: " autofocus" */
@@ -1101,11 +1109,11 @@
1101 @ <div class='searchForm searchForm%s(zClass)'>
1102 }else{
1103 @ <div class='searchForm'>
1104 }
1105 @ <input type="text" name="s" size="40" value="%h(zPattern)"%s(zDisable1)>
1106 if( useYparam && (srchFlags & (srchFlags-1))!=0 && useYparam ){
1107 static const struct { char *z; char *zNm; unsigned m; } aY[] = {
1108 { "all", "All", SRCH_ALL },
1109 { "c", "Check-ins", SRCH_CKIN },
1110 { "d", "Docs", SRCH_DOC },
1111 { "t", "Tickets", SRCH_TKT },
@@ -1146,11 +1154,13 @@
1146 }
1147 if( search_run_and_output(zPattern, srchFlags, fDebug)==0 ){
1148 @ <p class='searchEmpty'>No matches for: <span>%h(zPattern)</span></p>
1149 }
1150 @ </div>
 
1151 }
 
1152 }
1153
1154 /*
1155 ** WEBPAGE: search
1156 **
1157
--- src/search.c
+++ src/search.c
@@ -1066,20 +1066,27 @@
1066 **
1067 ** This routine automatically restricts srchFlag according to user
1068 ** permissions and the server configuration. The entry box is shown
1069 ** disabled if srchFlags is 0 after these restrictions are applied.
1070 **
1071 ** The mFlags value controls options:
1072 **
1073 ** 0x01 If the y= query parameter is present, use it as an addition
1074 ** restriction what to search.
1075 **
1076 ** 0x02 Show nothing if search is disabled.
1077 **
1078 ** Return true if there are search results.
1079 */
1080 int search_screen(unsigned srchFlags, int mFlags){
1081 const char *zType = 0;
1082 const char *zClass = 0;
1083 const char *zDisable1;
1084 const char *zDisable2;
1085 const char *zPattern;
1086 int fDebug = PB("debug");
1087 int haveResult = 0;
1088 srchFlags = search_restrict(srchFlags);
1089 switch( srchFlags ){
1090 case SRCH_CKIN: zType = " Check-ins"; zClass = "Ckin"; break;
1091 case SRCH_DOC: zType = " Docs"; zClass = "Doc"; break;
1092 case SRCH_TKT: zType = " Tickets"; zClass = "Tkt"; break;
@@ -1086,10 +1093,11 @@
1093 case SRCH_WIKI: zType = " Wiki"; zClass = "Wiki"; break;
1094 case SRCH_TECHNOTE: zType = " Tech Notes"; zClass = "Note"; break;
1095 case SRCH_FORUM: zType = " Forum"; zClass = "Frm"; break;
1096 }
1097 if( srchFlags==0 ){
1098 if( mFlags & 0x02 ) return 0;
1099 zDisable1 = " disabled";
1100 zDisable2 = " disabled";
1101 zPattern = "";
1102 }else{
1103 zDisable1 = ""; /* Was: " autofocus" */
@@ -1101,11 +1109,11 @@
1109 @ <div class='searchForm searchForm%s(zClass)'>
1110 }else{
1111 @ <div class='searchForm'>
1112 }
1113 @ <input type="text" name="s" size="40" value="%h(zPattern)"%s(zDisable1)>
1114 if( (mFlags & 0x01)!=0 && (srchFlags & (srchFlags-1))!=0 ){
1115 static const struct { char *z; char *zNm; unsigned m; } aY[] = {
1116 { "all", "All", SRCH_ALL },
1117 { "c", "Check-ins", SRCH_CKIN },
1118 { "d", "Docs", SRCH_DOC },
1119 { "t", "Tickets", SRCH_TKT },
@@ -1146,11 +1154,13 @@
1154 }
1155 if( search_run_and_output(zPattern, srchFlags, fDebug)==0 ){
1156 @ <p class='searchEmpty'>No matches for: <span>%h(zPattern)</span></p>
1157 }
1158 @ </div>
1159 haveResult = 1;
1160 }
1161 return haveResult;
1162 }
1163
1164 /*
1165 ** WEBPAGE: search
1166 **
1167

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button