summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pttbbs/include/proto.h1
-rw-r--r--pttbbs/mbbsd/brc.c69
-rw-r--r--pttbbs/mbbsd/read.c56
-rw-r--r--pttbbs/sample/etc/board.help1
4 files changed, 127 insertions, 0 deletions
diff --git a/pttbbs/include/proto.h b/pttbbs/include/proto.h
index 9e5b26df..b7882091 100644
--- a/pttbbs/include/proto.h
+++ b/pttbbs/include/proto.h
@@ -115,6 +115,7 @@ int brc_initial_board(const char *boardname);
// v3 api: add 'modified' tag
int brc_unread(int bid, const char *fname, time4_t modified);
int brc_unread_time(int bid, time4_t ftime,time4_t modified);
+int brc_search_read(int bid, time4_t ftime, int forward, time4_t *result);
void brc_addlist(const char* fname, time4_t modified);
void brc_update(void);
void brc_toggle_all_read(int bid, int is_all_read);
diff --git a/pttbbs/mbbsd/brc.c b/pttbbs/mbbsd/brc.c
index bedb2e1a..8f7bf5ba 100644
--- a/pttbbs/mbbsd/brc.c
+++ b/pttbbs/mbbsd/brc.c
@@ -646,3 +646,72 @@ brc_unread(int bid, const char *fname, time4_t modified)
return brc_unread_time(bid, ftime, modified);
}
+
+/*
+ * 從 ftime 該篇文章開始, 往上或往下尋找第一篇已讀過的文章
+ * forward == 1: 往更新的文章找 (往下找)
+ *
+ * 假設: blist[] 是按照 .create 由大而小往後排序好的.
+ *
+ * Return: 0 -- 沒有任何已讀的文章
+ * 1 -- 找到已讀文章, 並將該文章放在 result 中傳回.
+ */
+int
+brc_search_read(int bid, time4_t ftime, int forward, time4_t *result)
+{
+ int i;
+ int bnum;
+ const brc_rec *blist;
+
+ brc_initialize();
+
+ if (brc_currbid && bid == brc_currbid) {
+ blist = brc_list;
+ bnum = brc_num;
+ } else {
+ blist = brc_find_record(bid, &bnum);
+ }
+
+ // [0].create is the biggest.
+ // 首先要找到 ftime 所在的區間, 然後再視 forward 的值來取前後的已讀文章.
+ for( i = 0; i < bnum; i++ ) { /* using linear search */
+ if( ftime > blist[i].create ) {
+ if( forward ) {
+ if( i ) {
+ goto return_older;
+ } else {
+ return 0;
+ }
+ } else {
+ // 回傳此篇已讀文章
+ if( result ) *result = blist[i].create;
+ return 1;
+ }
+ }
+ // 游標所在的檔案本身就是已讀過
+ else if( ftime == blist[i].create ) {
+ if( forward && i ) {
+ goto return_older;
+ } else if( !forward && (i + 1) < bnum ) {
+ goto return_newer;
+ }
+ return 0;
+ }
+ }
+ // 區間落在最後一個的後面 (更早之前的文章)
+ if ( forward && i ) {
+ goto return_older;
+ }
+ return 0;
+
+return_older:
+ // 回傳後一篇已讀文章
+ if( result ) *result = blist[i - 1].create;
+ return 1;
+
+return_newer:
+ // 回傳前一篇已讀文章
+ if( result ) *result = blist[i + 1].create;
+ return 1;
+}
+
diff --git a/pttbbs/mbbsd/read.c b/pttbbs/mbbsd/read.c
index 1999d82a..50e24561 100644
--- a/pttbbs/mbbsd/read.c
+++ b/pttbbs/mbbsd/read.c
@@ -330,6 +330,54 @@ thread(const keeploc_t * locmem, int stypen)
return new_ln;
}
+/*
+ * 根據 stypen 選擇上/下一篇已讀過的文章
+ *
+ * @param locmem 用來存在某看板游標位置的 structure。
+ * @param stypen 游標移動的方法
+ * CURSOR_NEXT, CURSOR_PREV:
+ * 與游標目前位置的文章同標題 的 下一篇/前一篇 文章。
+ *
+ * @return 新的游標位置
+ */
+static int
+search_read(const int bid, const keeploc_t * locmem, int stypen)
+{
+ fileheader_t fh;
+ int pos = locmem->crs_ln;
+ int rk;
+ int fd = -1;
+ int forward = (stypen & RS_FORWARD) ? 1 : 0;
+ time4_t ftime, result;
+
+ if( last_line <= 1 ) return pos;
+
+ /* First load the timestamp of article where cursor pointing to */
+ rk = get_record_keep(currdirect, &fh, sizeof(fileheader_t), pos, &fd);
+ if( fd < 0 || rk < 0) return pos;
+ ftime = atoi( &fh.filename[2] );
+
+ /* given the ftime to resolve the read article */
+ if( brc_search_read(bid, ftime, forward, &result ) ) {
+ int i;
+ int step = forward ? 1 : -1;
+
+ /* find out the position for the article result */
+ for( i = pos; i >= 0 && i <= last_line; i += step ) {
+ rk = get_record_keep(currdirect, &fh, sizeof(fileheader_t), i, &fd);
+ if( fd < 0 || rk < 0) goto out;
+ if (atoi( &fh.filename[2] ) == result ) {
+ pos = i;
+ goto out;
+ }
+ }
+ }
+
+out:
+ if( fd != -1 ) close(fd);
+ return pos;
+}
+
static int
select_by_aid(const keeploc_t * locmem, int *pnew_ln, int *pnewdirect_new_ln,
char *pdefault_ch)
@@ -999,6 +1047,14 @@ i_read_key(const onekey_t * rcmdlist, keeploc_t * locmem,
}
break;
+ case '{':
+ new_ln = search_read(bid, locmem, READ_PREV);
+ break;
+
+ case '}':
+ new_ln = search_read(bid, locmem, READ_NEXT);
+ break;
+
case KEY_ENTER:
case 'l':
case KEY_RIGHT:
diff --git a/pttbbs/sample/etc/board.help b/pttbbs/sample/etc/board.help
index 4b9653a4..99181de1 100644
--- a/pttbbs/sample/etc/board.help
+++ b/pttbbs/sample/etc/board.help
@@ -5,6 +5,7 @@
(數字鍵) 跳到指定號碼的文章 (Home)/(End/$) 跳到首篇/末篇文章
(r)(→) 閱讀此篇文章 (=[]<>-+S) 主題式閱讀
(^P)/(y)/(X) 發表/回覆/推薦文章 (F/U)/(^X) 轉寄至信箱/轉錄至其它看板
+ ({)/(}) 跳到下篇已讀文章/上篇
【 進階命令 】
(/)(?)/(a)/(Z) 搜尋 關鍵字/作者/推文數 (^H)/(!) 只列主要標題/不列關鍵字